상세 컨텐츠

본문 제목

[Java] 다른 프로그램 프로세싱 관리, 프로그램 죽으면 다시 실행 시키기 관련, 자바로 외부파일 실행.

JAVA

by AlrepondTech 2020. 9. 18. 01:32

본문

반응형

 

 

 

=======================

=======================

=======================

 

 

 

 

 

 

 

 

출처: http://ibabo.tistory.com/269

 

가. 프로세스 생성 및 종료

 

반적으로 프로그램을 실행시키면, 하나의 프로세스로서 동작하게 됩니다. 다시 말해서, 우리가 실행시키는 하나의 프로그램은 하나의 프로세스로서 나타나게 됩니다. 자바에서의 프로세스는 자바 런타임 환경과 밀접한 관계를 갖고 있습니다. 왜냐하면, 자바 런타임 환경은 프로세스가 실행될 수 있는 기반 환경을 제공해 주기 때문입니다. 프로세스는 다른 프로세스를 생성할 수 있는데, 이 때 생성된 프로세스를 자식 프로세스라하고 기존에 있던 프로세스를 부모 프로세스라 합니다. 이러한 부모/자식 프로세스 개념은 하나의 자바 프로그램에서 다른 프로그램을 실행시키고자 할 때, 주로 사용됩니다. 다시 말해서, 플랫폼 독립적인 자바 프로그램이 플랫폼과 밀접한 관련이 있는 작업을 해야 할 경우, 해당 작업을 수행할 프로그램을 다른 언어로 해당 플랫폼에 맞도록 작성하고, 이 프로그램을 자바 프로그램에서 실행시켜 주는 것입니다.

이를 위해, 플랫폼 종속적인 시스템 함수들을 호출할 수 있도록 해 주는 Runtime 클래스와 실행하고자 하는 응용프로그램을 위한 프로세스를 관리할 수 있도록 해 주는 Process 클래스를 사용할 수 있습니다. 자바에서 프로세스를 생성하기 위하여 다음과 같이 해 줍니다.

 

- “Runtime runtime = Runtime.getRuntime();”: 런타임 객체를 생성합니다.
- “Process p = runtime.exec(“프로그램경로명”);”: exec 메소드를 이용하여 프로세스를 생성합니다.

위와 같이 프로세스를 생성할 수 있고, 프로세스의 작업을 마치거나 또는 프로세스를 강제고 종료하기 위해서는 다음 중 한 가지 방법으로 할 수 있습니다.

- “p.waitFor();”: 자식 프로세스가 종료될 때까지 기다립니다.
- “p.destroy();”: 부모 프로세스에서 자식 프로세스를 강제로 종료시킵니다.
- “System.exit(0);”: 부모 프로세스만 종료되고 자식 프로세스는 계속 실행됩니다.

Runtime 클래스가 제공해 주는 주요 메소드를 살펴보면 다음과 같습니다.

- public static Runtime getRuntime(): 현재 실행되고 있는 자바 애플리케이션과 
관련된 런타임 객체를 리턴해 줍니다.

- public void exit(int status): 현재 자바 가상머신을 종료합니다. 
status 매개변수는 종료시의 상태값을 나타내며, 
일반적으로 0 이외의 값은 비정상적으로 종료되었음을 의미합니다.

- public Process exec(String command) throws IOException: 주어진 명령어를 독립된 프로세스로 
실행시켜 줍니다. exec(command, null)와 같이 실행시킨 것과 같습니다.

- public Process exec(String command, String envp[]) throws IOException: 주어진 명령어를 
주어진 환경을 갖는 독립된 프로세스로 실행시켜 줍니다. 이 메소드는 명령어 문자열을 토큰으로 
나누어 이 토큰들을 포함하고 있는 cmdarray라는 새로운 배열을 생성합니다. 
그리고 나서 exec(cmdarray, envp)을 호출합니다.

- public Process exec(String cmdarray[]) throws IOException: 주어진 문자열 배열에 있는 명령어와 
매개변수를 이용하여 독립된 프로세스로 실행시켜 줍니다. exec(cmdarray, null)을 호출합니다.

- public Process exec(String cmdarray[], String envp[]) throws IOException: 주어진 문자열 
배열에 있는 명령어와 매개변수를 이용하여 주어진 환경을 갖는 독립된 프로세스로 실행시켜 줍니다. 
문자열 배열 cmdarray에는 명령어와 명령행 인자들을 나타내고 있습니다.

- public native long freeMemory(): 시스템에 남아있는 메모리의 양을 얻습니다. 이 값은 
항상 totalMemory() 메소드에 의해 얻어지는 값보다 작습니다.

- public native long totalMemory(): 자바 가상머신의 최대 메모리 크기를 얻습니다.

Process 클래스가 제공해 주는 주요 메소드를 살펴보면 다음과 같습니다.

- public abstract OutputStream getOutputStream(): 자식 프로세스의 출력 스트림을 얻습니다. 

- public abstract InputStream getInputStream(): 자식 프로세스의 입력 스트림을 얻습니다. 

- public abstract InputStream getErrorStream(): 자식 프로세스의 에러 스트림을 얻습니다. 

- public abstract int waitFor() throws InterruptedException: 자식 프로세스가 종료될 때까지 기다립니다. 

- public abstract int exitValue(): 자식 프로세스가 종료할 때의 상태값을 얻습니다. 

- public abstract void destroy(): 자식 프로세스를 강제로 종료시킵니다.

 

다음에 나오는 자바 프로그램은 위의 Runtime 클래스 및 Process 클래스를 이용하여 새로운 프로세스를 생성하고 종료하는 과정을 보여주기 위해 윈도우의 계산기를 실행시키는 간단한 예제입니다.

import java.io.*;

public class ProcessTest {

    static public void main(String args[]) {

        try {

            Process p1 = Runtime.getRuntime().exec("calc.exe");

            Process p2 = Runtime.getRuntime().exec("freecell.exe");

            Process p3 = Runtime.getRuntime().exec("Notepad.exe");

            p1.waitFor();

            p2.destroy();

            System.out.println("Exit value of p1: " + p1.exitValue());

            System.out.println("Exit value of p2: " + p2.exitValue());

        } catch (IOException e) {

            System.out.println(e.getMessage());

        } catch (InterruptedException e) {

            System.out.println(e.getMessage());

        }

        System.exit(0);

    }

}

/*

 * Results:

 D:AIITJAVA6>java ProcessTest

 Exit value of p1: 0

 Exit value of p2: 1

 D:AIITJAVA6>

 */

<프로그램 1. ProcessTest.java>나. 상호작용 명령어의 실행

그런데, 위와 같이 프로세스를 이용하여 방식으로 명령어를 실행하다 보면, 명령어에 따라 사용자에게 메시지를 출력하고 이에 대한 적절한 답을 사용자로부터 입력 받기를 원하는 명령어가 있습니다. 이러한 명령어를 상호작용(interactive) 명령어라고 합니다.

D:AIITJAVA6>ping 203.252.134.126
Pinging 203.252.134.126 with 32 bytes of data:
Reply from 203.252.134.126: bytes=32 time<10ms TTL=128
Reply from 203.252.134.126: bytes=32 time<10ms TTL=128
Reply from 203.252.134.126: bytes=32 time<10ms TTL=128
Reply from 203.252.134.126: bytes=32 time<10ms TTL=128
D:AIITJAVA6>

<그림 1. 상호작용 명령어의 실행>

그림에서와 같이 ping 명령어를 실행시키게 되면, ping 명령어는 그 실행 결과를 표준 출력을 이용하여 화면상에 출력해 줍니다. 이렇게 자바에서 실행시킨 프로세스가 출력하는 결과를 자바 프로그램은 알아야 하고, 또한 프로세스가 자바 프로그램으로부터 어떤 대답을 원할 경우가 있는데 이 때 사용자는 이에 대해 적절하게 답을 해 주어야 합니다. 이 때, ping 명령어는 메시지를 자신의 표준 출력에 장치에 출력하게 되는데, 이렇게 프로세스의 표준 출력을 자바 프로그램에서는 p.getInputStream 메소드를 이용하여 얻고, p.getOutputStream 메소드를 이용하여 프로세스의 표준 입력 장치에 쓰게 됩니다. 이 때, 한 가지 주의할 사항은 표준 출력 스트림에 대답을 쓴(write) 후, 꼭 flush 또는 close 메소드를 이용하여 표준 출력 스트림을 비워(flush) 주어야 합니다.

 

<그림 2. 자바 프로그램과 프로세스 간의 데이터의 전달>

다음에 나오는 자바 프로그램은 도스 상에서 상호작용 명령어를 사용하는 간단한 예제를 보여줍니다.

 

import java.io.*;

import java.lang.*;

public class InteractiveProcessTest {

    public static void main(String[] args) {

        try {

            Process p = Runtime.getRuntime().exec("ping 203.252.134.126");

            byte[] msg = new byte[128];

            int len;

            while ((len = p.getInputStream().read(msg)) > 0) {

                System.out.print(new String(msg, 0, len));

            }

            String rs = "n";

            byte[] rb = new byte[] {
                (byte)
                'n'
            }; //rs.getBytes();

            OutputStream os = p.getOutputStream();

            os.write(rb);

            os.close();

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

}

/*

 * Results:

 D:AIITJAVA6>java InteractiveProcessTest

 Pinging 203.252.134.126 with 32 bytes of data:

 Reply from 203.252.134.126: bytes=32 time<10ms TTL=128

 Reply from 203.252.134.126: bytes=32 time<10ms TTL=128

 Reply from 203.252.134.126: bytes=32 time<10ms TTL=128

 Reply from 203.252.134.126: bytes=32 time<10ms TTL=128

 D:AIITJAVA6>

*/

<프로그램 2. InteractiveProcessTest.java>

 

 

 

=======================

=======================

=======================

 

 

 

출처: http://linuxism.tistory.com/1077

 

 

자바에서 배치파일(.batch)뿐만 아니라 DOS 커맨드, 실행파일(.exe) 파일도 실행 가능하다

 

1. java에서 배치파일 실행하기 (DOS 명령어, exe 실행파일)

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class ManucalDBBackup{
  try {
    Process p =Runtime.getRuntime().exec("C:\\Tomcat 5.5\\webapps\\TEST.bat");
    
    BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
    String line = null;
    
    while ((line = br.readLine()) != null) {
      System.out.println(line);
    }
  } catch (Exception e) {
    System.err.println(e);
  }
}

 

자바소스를 실행하면, 일반 명령어나 배치파일의 실행결과가 consol에 뿌려지면서 실행이 된다.ㅋ

 

2. java에서 ORACLE DB 백업(exp 명령어) 실행하기

[오라클 DB 백업 배치파일 내용]

@echo off
  d:
  cd D:\BackUp\aBisManager\backupDB
  setlocal
  set date2=%date:-=%
  set time2=%time: =0%
  set time3=%time2:~0,2%%time2:~3,2%%time:~6,2%
  set DS=%date2%_%time3%
  mkdir %DS%
  exp userid=userid/userpwd file='D:\BackUp\%DS%\TEST.dmp'

        log='D:\BackUp\%DS%\TEST.log' tables=(userid.xx, userid.yy) statistics=none
  endlocal
  @echo on

 

로컬에서..

오라클 백업 명령 배치파일을 그냥 실행하면 되는데

웹상(was : 톰캣)에서..
java를 통해 호출하면 계속 hang이 걸려버린다.. -ㅇ-;;
이 상태에서 톰캣을 꺼버리면 바로 백업이 완료되는 시츄에이션이 계속 되고..
톰캣을 안 끄고
걍 시간을 두고 보니 약 한시간 반 뒤에 백업파일이 생성되는 황당함ㅋ
이유가 무엇일까?
많은 국내 사이트를 돌아다녀봤는데.. 모두들 비슷한 문제를 겪고 있었다.
모두들 엉뚱한 소리만 하고,,
눈을 돌려.. 해외로~
해외에도 동일한 문제로 고민을 하는 많은 사람들.
... 하지만 해답을 제시하는 사람 몇몇 발견!!!

 

찾았다~!! ㅠㅠ


원인은 exp 명령어가 실행되면 output을 만들게 되는데 이를 (표준)출력 해주지 않으면 버퍼에 가득차 버려서 버퍼가 비워지길 기다리게 되면서 hang상태가 되는 것.


결론은 java에서 exp배치파일을 실행하면서 동시에 thread를 이용하여 표준출력을 해주는 것

 

소스 :

http://www.objects.com.au/java/examples/io/examples/ConsoleExecExample.java

http://www.objects.com.au/java/examples/io/AutoReader.java

 

출처 - http://blog.daum.net/nsh777/5494230

 

 

CmdExecutor.java
0.00MB

 

출처 - http://blog.daum.net/istae0430/246

 

아시다시피 위 함수는 process 를 실행시키기 위한 것입니다.
그런데 만약 프로세스의 수행이 끝이 날때까지 기다려야 한다면 어떻게 할까요?

일반적으로 아래와 같이 waitFor() 를 호출해 줍니다.

Process process = Runtime.getRuntime().exec(cmd);

process.waitFor(); 


문제는 waitFor() 가 영원히 끝나지 않는 경우가 발생한다는 것입니다.
분명히 cmd 에 해당하는 프로세스가 종료되어야 하는데, 이상하게도 끝나지 않는다는 이야깁니다.

원인은 stream 의 버퍼가 비워지지 않았기 때문입니다.
이를 비워줌으로써 문제를 해결할 수 있습니다.

그럼 어떻게 비워주면 될까요?
waitFor() 함수를 호출하는 순간, Thread 는 process 가 종료될때까지 block 이 됩니다.
다시 말해서 해당 stream 을 비워주는 작업을 별도의 thread 에서 수행해야 한다는 이야기죠.

별도 Thread 를 만들고, 이 Thread 에서 process.getErrorStream();  process.getInputStream(); 를 통해 Stream 을 얻어온 뒤, 계속해서 read 해 줌으로써 스트림을 비워야 한다는 것입니다.

만약, process 수행결과 얻어지는 출력을 필요로 하지 않는다면 코드는 훨씬 간단해 집니다.
아래처럼 애초에 stream 을 close 해 버리면 되거든요. :)

Process process = Runtime.getRuntime().exec(cmd);
process.getErrorStream().close();
process.getInputStream().close();
process.getOutputStream().close();
process.waitFor(); 

 

문제없이 process 가 실행 후, waitFor() 에서 빠져가나는 것을 확인하실 수 있습니다.

 

출처 - http://crystalcube.co.kr/69

 

 

자바에서 Runtime.getRuntime().exec() 를 사용하여 windows 명령어를 실행하는 방법.

여기서 command는 실행 명령어 이다.

예 : move c:\data\source.txt c:\data\target.txt  <- 윈도우용 

예 : mv /data/source.txt /data/target.txt <- 리눅스용

Process process;
String osName = System.getProperty("os.name");
String[] cmd;

if(osName.toLowerCase().startsWith("window")) {
    cmd = new String[] { "cmd.exe", "/y", "/c", command };
} else {
    cmd = new String[] { "/bin/sh", "-c", command };
}


process = Runtime.getRuntime().exec(cmd);

return process.waitFor();

 

출처 - http://blog.daum.net/lkflower/17224498

 

 

시스템 명령어 테스트 샘플 소스

-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

import java.io.*;

public class Test

{

    public static void main(String[] args) throws IOException, InterruptedException

    {

        String servlet_path = "C:\resin1.2.3\doc\WEB-INF\classes";

        String sourceDir = System.getProperty("user.dir") + File.separator + "source" + File.separator + "*.java";

        String comstr = "javac -d " + servlet_path + " " + sourceDir;

        Process proc = Runtime.getRuntime().exec(comstr);

        proc.waitFor();

        //주의: 윈도우의 경우 servlet_path는 구분문자가 \ 인데, sourceDir는 로 나온다.

        //배열을 안쓰고 문자열로 직접하는게 잘될 때가 있다.

    }

}

-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

import java.io.*;

public class Test

{

    public static void main(String[] args)

    {

        try

        {

            String comstr = "chmod 777 test.txt";

            String[] command = {
                "/bin/bsh",
                "-c",
                comstr
            };

            Process proc = Runtime.getRuntime().exec(command);

            proc.waitFor();

            if (proc.exitValue() != 0)

                out.println("에러...");

            proc.destroy();

        } catch (Exception e) {
            System.out.println(e);
        }

    }

}

-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

import java.io.*;

public class Test

{

    public static void main(String[] args)

    {

        try

        {

            String comstr = "ls -l";

            String[] command = {
                "/bin/bsh",
                "-c",
                comstr
            }; //리눅스에서

            //String [] command = { "/bin/csh", "-c", comstr }; // Unix에서

            //String [] command = { "command.com", "/c", comstr }; // 윈도우에서

            Process proc = Runtime.getRuntime().exec(command);

            proc.waitFor();

            if (proc.exitValue() != 0)

            {

                BufferedReader err = new BufferedReader(new InputStreamReader(proc.getErrorStream()));

                while (err.ready())

                    System.out.println(err.readLine());

                err.close();

            } else

            {

                BufferedReader out = new BufferedReader(new InputStreamReader(proc.getInputStream()));

                while (out.ready())

                    System.out.println(out.readLine());

                out.close();

            }

            proc.destroy();

        } catch (Exception e) {
            System.out.println(e);
        }

    }

}

-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

2. 리눅스 시스템 명령어 실행 결과를 받아오기

-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

String command = "ls";

String data = null;

StringBuffer strbuf = new StringBuffer();

BufferedReader br = null;

try

{
    Process proc = Runtime.getRuntime().exec(command);

    br = new BufferedReader(new InputStreamReader(proc.getInputStream()));

    String line;

    while ((line = br.readLine()) != null)

        strbuf.append(line + " ");

    br.close();

} catch (Exception e) {
    out.println(e);
}

data = strbuf.toString();

-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

 

3. 상호작용(interactive) 명령어의 실행

 

프로세스의 표준 출력을 자바 프로그램에서는 p.getInputStream 메소드를 이용하여 얻고,

p.getOutputStream 메소드를 이용하여 프로세스의 표준 입력 장치에 쓰게 됩니다.

이 때, 한 가지 주의할 사항은 표준 출력 스트림에 대답을 쓴(write) 후, 꼭 flush 또는 close 메소드를 이용하여

표준 출력 스트림을 비워(flush) 주어야 합니다.

------------------------------------------------------------------------

import java.io.*;

public class InteractiveProcessTest

{

    public static void main(String[] args)

    {

        // 반드시 배열로 해야한다. 문자열로 하면 단지 전체를 하나의 프로그램으로 인식한다.

        String[] command = {
            "ping",
            "203.252.134.126"
        };

        try

        {

            Process p = Runtime.getRuntime().exec(command);

            byte[] msg = new byte[128];

            int len;

            while ((len = p.getInputStream().read(msg)) > 0)

                System.out.print(new String(msg, 0, len));

            String rs = " ";

            byte[] rb = new byte[] {
                (byte)
                ' '
            }; //rs.getBytes();

            OutputStream os = p.getOutputStream();

            os.write(rb);

            os.close();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

 

------------------------------------------------------------------------

결과 :

C:>java InteractiveProcessTest

Pinging 203.252.134.126 with 32 bytes of data:

Reply from 203.252.134.126: bytes=32 time<10ms TTL=128

Reply from 203.252.134.126: bytes=32 time<10ms TTL=128

 

4. 명령어 문자열의 안정적인 작성 예

------------------------------------------------------------------------

// Unix에서

String [] command = { "/bin/csh", "-c", "finger | grep -v 639" };

// 윈도우에서

String [] command = { "command.com", "/c", "finger | grep -v 639" };

 

//getInputStream ( ) 스트림으로 결과값을 받아올 때 형변환해서 받을 수 없다.

String data = "";

BufferedReader out = new BufferedReader(new InputStreamReader(proc.getInputStream()));

data = out.readLine(); //int count = Integer.parseInt ( out.readLine ( ) );는 안된다.

out.close();

int count = Integer.parseInt(data);

------------------------------------------------------------------------

 

5. 프로세스 함수들

 

5.1 프로세스의 생성 및 종료

------------------------------------------------------------------------

- “Runtime runtime = Runtime.getRuntime();”: 런타임 객체를 생성합니다.

- “Process p = runtime.exec(“프로그램경로명”);”: exec 메소드를 이용하여 프로세스를 생성합니다.

- “p.waitFor();”: 자식 프로세스가 종료될 때까지 기다립니다.

- “p.destroy();”: 부모 프로세스에서 자식 프로세스를 강제로 종료시킵니다.

- “System.exit(0);”: 부모 프로세스만 종료되고 자식 프로세스는 계속 실행됩니다.

------------------------------------------------------------------------

 

5.2 Runtime 클래스가 제공해 주는 주요 메소드

------------------------------------------------------------------------

- public static Runtime getRuntime(): 현재 실행되고 있는 자바 애플리케이션과 관련된 런타임 
객체를 리턴해 줍니다.

- public void exit(int status): 현재 자바 가상머신을 종료합니다. status 매개변수는 종료시의
상태값을 나타내며,일반적으로 0 이외의 값은 비정상적으로 종료되었음을 의미합니다.

- public Process exec(String command) throws IOException: 주어진 명령어를 독립된 프로세스로 
실행시켜 줍니다. exec(command, null)와 같이 실행시킨 것과 같습니다.

- public Process exec(String command, String envp[]) throws IOException: 주어진 명령어를 주어진
환경을 갖는 독립된 프로세스로 실행시켜 줍니다. 이 메소드는 명령어 문자열을 토큰으로 나누어 이 
토큰들을 포함하고 있는 cmdarray라는 새로운 배열을 생성합니다. 
그리고 나서 exec(cmdarray, envp)을 호출합니다.

- public Process exec(String cmdarray[]) throws IOException:
주어진 문자열 배열에 있는 명령어와 매개변수를 이용하여 독립된 프로세스로 실행시켜 줍니다.
exec(cmdarray, null)을 호출합니다.

- public Process exec(String cmdarray[], String envp[]) throws IOException:
주어진 문자열 배열에 있는 명령어와 매개변수를 이용하여 주어진 환경을 갖는 독립된 프로세스로 
실행시켜 줍니다. 문자열 배열 cmdarray에는 명령어와 명령행 인자들을 나타내고 있습니다.

- public native long freeMemory(): 시스템에 남아있는 메모리의 양을 얻습니다.
이 값은 항상 totalMemory() 메소드에 의해 얻어지는 값보다 작습니다.

- public native long totalMemory(): 자바 가상머신의 최대 메모리 크기를 얻습니다.

 

------------------------------------------------------------------------

 

5.3 Process 클래스가 제공해 주는 주요 메소드

------------------------------------------------------------------------

- public abstract OutputStream getOutputStream(): 자식 프로세스의 출력 스트림을 얻습니다.

- public abstract InputStream getInputStream(): 자식 프로세스의 입력 스트림을 얻습니다.

- public abstract InputStream getErrorStream(): 자식 프로세스의 에러 스트림을 얻습니다.

- public abstract int waitFor() throws InterruptedException: 자식 프로세스가 종료될 때까지 기다립니다.

- public abstract int exitValue(): 자식 프로세스가 종료할 때의 상태값을 얻습니다.

- public abstract void destroy(): 자식 프로세스를 강제로 종료시킵니다.

------------------------------------------------------------------------

 

6. 메모리 관리

------------------------------------------------------------------------

public long totalMemory ( ) : 현재 할당받은 총 시스템 메모리 바이트 갯수.

public long freeMemory ( ) : 현재 남아 있는 자유 메모리 바이트 갯수(근사치).

Runtime rt = Runtime.getRuntime ( );

System.out.println ( rt.totalMemory ( ) );

System.out.println ( rt.freeMemory ( ) );

------------------------------------------------------------------------

 

 

나. 시스템 정보

static PrintStream err - The "standard" error output stream.

static InputStream in - The "standard" input stream.

static PrintStream out - The "standard" output stream.

 

static void arraycopy (Object src, int src_position, Object dst, int dst_position, int length)

static long currentTimeMillis () - Returns the current time in milliseconds.

static void exit (int status) - Terminates the currently running Java Virtual Machine.

static void gc () - Runs the garbage collector.

static String getenv (String name) - Deprecated from getProperty method

 

static Properties getProperties() - Determines the current system properties.

static String getProperty(String key) - Gets the system property indicated by the 
specified key.

static String getProperty(String key, String def) - Gets the system property 
indicated by the specified key.

static SecurityManager getSecurityManager() - Gets the system security interface.

static int identityHashCode(Object x) - Returns the same hashcode for the given
object as would be returned by the default method hashCode(), whether or not
the given object's class overrides hashCode().

static void load(String filename) - Loads a code file with the specified 
filename from the local file system as a dynamic library.

static void loadLibrary(String libname) - Loads the system library specified by 
the libname argument.

static String mapLibraryName(String libname) - Maps a library name into a 
platform-specific string representing a native library.

static void runFinalization() - Runs the finalization methods of any objects
pending finalization.

static void runFinalizersOnExit(boolean value) - Deprecated. This method is 
inherently unsafe. It may result in finalizers being called on live objects 
while other threads are concurrently manipulating those objects, resulting in 
erratic behavior or deadlock.

static void setErr(PrintStream err) - Reassigns the "standard" error output stream.

static void setIn(InputStream in) - Reassigns the "standard" input stream.

static void setOut(PrintStream out) - Reassigns the "standard" output stream.

static void setProperties(Properties props) - Sets the system properties to the 
Properties argument.

static String setProperty(String key, String value) - Sets the system property 
indicated by the specified key.

static void setSecurityManager(SecurityManager s)

String System.getProperty ( String key ): key에 해당하는 시스템정보를 가져온다.

String System.setProperty ( String key, String value )

Properties System.getProperties ( ): 시스템 정보를 몽땅 갖고 온다.

System.setProperties ( Properties props )

 

사용법

------------------------------------------------------------------------

String currentDirectory = System.getProperty ( "user.dir" );

------------------------------------------------------------------------

 

Key값

------------------------------------------------------------------------

// 일반적으로, 보안에 걸리지 않는 표준 시스템 프로퍼티

"java.version", // 자바의 버전 ( "1.0.2", "1.1", "1.1.3", "1.2", ...)

"java.class.version", // 자바 클래스 화일 포맷 버전

"java.vendor", // 자바 가상 머쉰 판매 회사

"java.vendor.url", // 자바 가상 머쉰 판매 회사의 URL

"os.name", // 운영체제 이름 ( "Windows 95", "Windows NT", "MacOS",

// "Linux", "Solaris", "OS/2", "OSF1", ... )

"os.version", // 운영체제 버전

"os.arch", // 컴퓨터 기종 ( "x86", "sparc", ... )

"line.separator", // 시스템에서의 행 분리 문자열 ( "

", " ", " " )

"file.separator", // 화일 경로 이름내의 디렉토리 구분 문자 ("", "/")

"path.separator", // 화일 경로 이름 리스트의 구분 문자 (";", ":")

 

// 일반적으로, 보안에 의한 접근 제한을 받는 표준 시스템 프로퍼티 (애플릿의 경우)

"java.home", // JDK 설치 디렉토리

"java.class.path", // 패키지가 있는 디렉토리 리스트

// (일반적으로, CLASSPATH 환경변수값에 의해 영향 받음)

"user.name", // 사용자의 등록 이름

"user.home", // 사용자의 홈 디렉토리

"user.dir", // 사용자의 현재 작업 디렉토리(파일을 뺀 전체 경로)

 

// JDK 1.1에서 비공식적으로 추가된 지역 정보 시스템 프로퍼티

// 일반적으로, 보안에 의한 접근 제한을 받음 (애플릿의 경우)

"file.encoding", // 사용자의 디폴트 문자 인코딩 이름

"user.language", // 사용자의 언어

"user.region", // 사용자의 거주 지역 (보통, 국가)

"user.timezone", // 사용자 지역의 표준 시간대 이름

 

// 웹 브라우저 정보 비표준 시스템 프로퍼티

"browser", // 웹 브라우저 이름

"browser.version", // 웹 브라우저 버전

"browser.vendor", // 웹 브라우저 회사

------------------------------------------------------------------------

 

 

다. 기타

 

//아래는 자바서비스넷의 이원영님 자료

-----------------------------------------------------------------------------------

import java.io.*;

public class Test

{

    public static void main(String[] args) throws Exception

    {

        Runtime rt = Runtime.getRuntime();

        StringBuffer cmd = new StringBuffer();

        for (int i = 0; i cmd.append(args[i] + " ");

            Process p = rt.exec(cmd.toString());

            PrintWriter keyboard = new PrintWriter(p.getOutputStream());

            //keyboard.println( ... );

            p.waitFor(); // wait for process finishing.

            BufferedReader out = new BufferedReader(new InputStreamReader(p.getInputStream()));

            while (out.ready())

                System.out.println(out.readLine());

            BufferedReader err = new BufferedReader(new InputStreamReader(p.getErrorStream()));

            while (err.ready())

                System.out.println(err.readLine());

            p.destroy(); //confirm

        }

    }

-----------------------------------------------------------------------------------

javaservice:/home/java/tmp$ javac Test.java

javaservice:/home/java/tmp$ java Test ls -alF /var

 

그러나 windows환경의 command.com의 경우, "command.com /c dir" 등의 방법으로

될 것으로 예상됐지만, "command.com /c dir" 의 명령이 보통의 DOS창에선 바로 exit으로

이어지나, Runtime.exec("command.com /c dir") 로 호출했을 경우, Process Thread가

끝나질 않는 군요... 결국, p.waitFor()에서 blocking 현상이 일어나네요.

어쨌거나 Unix환경에선 잘 되네요.

 

//아래는 이원영의 참고자료

-----------------------------------------------------------------------------------

import java.io.*;

public class Test

{

    public static void main(String[] args) throws Exception

    {

        Runtime rt = Runtime.getRuntime();
        String[] command = {
            "a.exe"
        };

        Process p = Runtime.getRuntime().exec(command);

        OutputStream os = p.getOutputStream();

        DataOutputStream dos = new DataOutputStream(os);

        dos.writeInt(...);

        dos.flush();

        os.close();

        p.waitFor();

        int rc = p.exitValue();

        System.out.println("return code: " + rc);

        if (rc != 0)

        {

            InputStream errStream = p.getErrorStream();

            DataInputStream errDataStream = new DataInputStream(errStream);

            String s;

            s = errDataStream.readLine();

            while (s != null)

            {

                System.out.println(s);

                s = errDataStream.readLine();

            }

        }

        InputStream is = p.getInputStream();

        DataInputStream dis = new DataInputStream(is);

        dis.readLine();

        is.close();
        StringBuffer cmd = new StringBuffer();

        for (int i = 0; i cmd.append(args[i] + " ");

            Process p = rt.exec(cmd.toString());

            PrintWriter keyboard = new PrintWriter(p.getOutputStream());

            //keyboard.println( ... );

            p.waitFor(); // wait for process finishing.

            BufferedReader out = new BufferedReader(new InputStreamReader(p.getInputStream()));

            while (out.ready())

                System.out.println(out.readLine());

            BufferedReader err = new BufferedReader(new InputStreamReader(p.getErrorStream()));

            while (err.ready())

                System.out.println(err.readLine());

            p.destroy(); //confirm

        }

    }

 

 

출처 - http://alethe.egloos.com/1853800

 

 

 

 

반응형

 

 

728x90

 

 

 

 

 

=======================

=======================

=======================

 

 

 

 

출처: http://tip.daum.net/question/145973

 

 

자바 - 자바로 프로세스 관리

자바로 윈도우의 프로세스를 관리하고 (실행하거나 실행중인 프로세서를 죽이는등...) 컴퓨터 전원을 끄는 그런 그능이 구현 가능한가요??

 

가. 프로세스 생성 및 종료

일반적으로 프로그램을 실행시키면, 하나의 프로세스로서 동작하게 됩니다. 다시 말해서, 우리가 실행시키는 하나의 프로그램은 하나의 프로세스로서 나타나게 됩니다. 자바에서의 프로세스는 자바 런타임 환경과 밀접한 관계를 갖고 있습니다. 왜냐하면, 자바 런타임 환경은 프로세스가 실행될 수 있는 기반 환경을 제공해 주기 때문입니다. 프로세스는 다른 프로세스를 생성할 수 있는데, 이 때 생성된 프로세스를 자식 프로세스라하고 기존에 있던 프로세스를 부모 프로세스라 합니다. 이러한 부모/자식 프로세스 개념은 하나의 자바 프로그램에서 다른 프로그램을 실행시키고자 할 때, 주로 사용됩니다. 다시 말해서, 플랫폼 독립적인 자바 프로그램이 플랫폼과 밀접한 관련이 있는 작업을 해야 할 경우, 해당 작업을 수행할 프로그램을 다른 언어로 해당 플랫폼에 맞도록 작성하고, 이 프로그램을 자바 프로그램에서 실행시켜 주는 것입니다.

이를 위해, 플랫폼 종속적인 시스템 함수들을 호출할 수 있도록 해 주는 Runtime 클래스와 실행하고자 하는 응용프로그램을 위한 프로세스를 관리할 수 있도록 해 주는 Process 클래스를 사용할 수 있습니다. 자바에서 프로세스를 생성하기 위하여 다음과 같이 해 줍니다.

 - “Runtime runtime = Runtime.getRuntime();”: 런타임 객체를 생성합니다.

 - “Process p = runtime.exec(“프로그램경로명”);”: exec 메소드를 이용하여 프로세스를 생성합니다.

 

위와 같이 프로세스를 생성할 수 있고, 프로세스의 작업을 마치거나 또는 프로세스를 강제고 종료하기 위해서는 다음 중 한 가지 방법으로 할 수 있습니다.

 - “p.waitFor();”: 자식 프로세스가 종료될 때까지 기다립니다.

 - “p.destroy();”: 부모 프로세스에서 자식 프로세스를 강제로 종료시킵니다.

 - “System.exit(0);”: 부모 프로세스만 종료되고 자식 프로세스는 계속 실행됩니다.

Runtime 클래스가 제공해 주는 주요 메소드를 살펴보면 다음과 같습니다.

- public static Runtime getRuntime(): 현재 실행되고 있는 자바 애플리케이션과 관련된 런타임 
객체를 리턴해 줍니다.

- public void exit(int status): 현재 자바 가상머신을 종료합니다. status 매개변수는 종료시의 
상태값을 나타내며, 일반적으로 0 이외의 값은 비정상적으로 종료되었음을 의미합니다.

- public Process exec(String command) throws IOException: 주어진 명령어를 독립된 프로세스로 
실행시켜 줍니다. exec(command, null)와 같이 실행시킨 것과 같습니다.

- public Process exec(String command, String envp[]) throws IOException: 주어진 명령어를 주어진
환경을 갖는 독립된 프로세스로 실행시켜 줍니다. 이 메소드는 명령어 문자열을 토큰으로 나누어 이 
토큰들을 포함하고 있는 cmdarray라는 새로운 배열을 생성합니다. 그리고 나서 exec(cmdarray, envp)을 
호출합니다.

- public Process exec(String cmdarray[]) throws IOException: 주어진 문자열 배열에 있는 명령어와 
매개변수를 이용하여 독립된 프로세스로 실행시켜 줍니다. exec(cmdarray, null)을 호출합니다.

- public Process exec(String cmdarray[], String envp[]) throws IOException: 주어진 문자열 
배열에 있는 명령어와 매개변수를 이용하여 주어진 환경을 갖는 독립된 프로세스로 실행시켜 줍니다. 
문자열 배열 cmdarray에는 명령어와 명령행 인자들을 나타내고 있습니다.

- public native long freeMemory(): 시스템에 남아있는 메모리의 양을 얻습니다. 이 값은 항상 
totalMemory() 메소드에 의해 얻어지는 값보다 작습니다.

- public native long totalMemory(): 자바 가상머신의 최대 메모리 크기를 얻습니다.

Process 클래스가 제공해 주는 주요 메소드를 살펴보면 다음과 같습니다.

- public abstract OutputStream getOutputStream(): 자식 프로세스의 출력 스트림을 얻습니다.

- public abstract InputStream getInputStream(): 자식 프로세스의 입력 스트림을 얻습니다.

- public abstract InputStream getErrorStream(): 자식 프로세스의 에러 스트림을 얻습니다.

- public abstract int waitFor() throws InterruptedException: 자식 프로세스가 종료될 때까지 
기다립니다.

- public abstract int exitValue(): 자식 프로세스가 종료할 때의 상태값을 얻습니다.

- public abstract void destroy(): 자식 프로세스를 강제로 종료시킵니다.

         

다음에 나오는 자바 프로그램은 위의 Runtime 클래스 및 Process 클래스를 이용하여 새로운 프로세스를 생성하고 종료하는 과정을 보여주기 위해 윈도우의 계산기를 실행시키는 간단한 예제입니다.

import java.io.*;

public class ProcessTest {

   static public void main(String args[]) {

      try {

         Process p1 = Runtime.getRuntime().exec("calc.exe");

         Process p2 = Runtime.getRuntime().exec("freecell.exe");

         Process p3 = Runtime.getRuntime().exec("Notepad.exe");

         p1.waitFor();

         p2.destroy();

         System.out.println("Exit value of p1: "+p1.exitValue());

         System.out.println("Exit value of p2: "+p2.exitValue());

      } catch(IOException e) {

         System.out.println(e.getMessage());

      } catch(InterruptedException e) {

         System.out.println(e.getMessage());

      }

      System.exit(0);

   }

}

/*

 * Results:

 D:AIITJAVA6>java ProcessTest

 Exit value of p1: 0

 Exit value of p2: 1

 D:AIITJAVA6>

 */

<프로그램 1. ProcessTest.java>

 

 

나. 상호작용 명령어의 실행

그런데, 위와 같이 프로세스를 이용하여 방식으로 명령어를 실행하다 보면, 명령어에 따라 사용자에게 메시지를 출력하고 이에 대한 적절한 답을 사용자로부터 입력 받기를 원하는 명령어가 있습니다. 이러한 명령어를 상호작용(interactive) 명령어라고 합니다.

D:AIITJAVA6>ping 203.252.134.126

Pinging 203.252.134.126 with 32 bytes of data:

Reply from 203.252.134.126: bytes=32 time<10ms TTL=128

Reply from 203.252.134.126: bytes=32 time<10ms TTL=128

Reply from 203.252.134.126: bytes=32 time<10ms TTL=128

Reply from 203.252.134.126: bytes=32 time<10ms TTL=128

D:AIITJAVA6>

<그림 1. 상호작용 명령어의 실행>

그림에서와 같이 ping 명령어를 실행시키게 되면, ping 명령어는 그 실행 결과를 표준 출력을 이용하여 화면상에 출력해 줍니다. 이렇게 자바에서 실행시킨 프로세스가 출력하는 결과를 자바 프로그램은 알아야 하고, 또한 프로세스가 자바 프로그램으로부터 어떤 대답을 원할 경우가 있는데 이 때 사용자는 이에 대해 적절하게 답을 해 주어야 합니다. 이 때, ping 명령어는 메시지를 자신의 표준 출력에 장치에 출력하게 되는데, 이렇게 프로세스의 표준 출력을 자바 프로그램에서는 p.getInputStream 메소드를 이용하여 얻고, p.getOutputStream 메소드를 이용하여 프로세스의 표준 입력 장치에 쓰게 됩니다. 이 때, 한 가지 주의할 사항은 표준 출력 스트림에 대답을 쓴(write) 후, 꼭 flush 또는 close 메소드를 이용하여 표준 출력 스트림을 비워(flush) 주어야 합니다.

<그림 2. 자바 프로그램과 프로세스 간의 데이터의 전달>

다음에 나오는 자바 프로그램은 도스 상에서 상호작용 명령어를 사용하는 간단한 예제를 보여줍니다.

 

import java.io.*;

import java.lang.*;

public class InteractiveProcessTest {

   public static void main(String[] args) {

      try {

         Process p = Runtime.getRuntime().exec("ping 203.252.134.126");

         byte[] msg = new byte[128];

         int len;

         while((len=p.getInputStream().read(msg)) > 0) {

            System.out.print(new String(msg, 0, len));

         }

         String rs = "n";

         byte[] rb  = new byte[] { (byte)'n' } ; //rs.getBytes();

         OutputStream os = p.getOutputStream();

         os.write(rb);

         os.close();

      } catch (Exception e) {

         e.printStackTrace();

      }

   }

}

/*

 * Results:

 D:AIITJAVA6>java InteractiveProcessTest

 Pinging 203.252.134.126 with 32 bytes of data:

 Reply from 203.252.134.126: bytes=32 time<10ms TTL=128

 Reply from 203.252.134.126: bytes=32 time<10ms TTL=128

 Reply from 203.252.134.126: bytes=32 time<10ms TTL=128

 Reply from 203.252.134.126: bytes=32 time<10ms TTL=128

 D:AIITJAVA6>

*/

<프로그램 2. InteractiveProcessTest.java>

 

 

 

=======================

=======================

=======================

 

 

 

 

출처: http://zero-gravity.tistory.com/166

 

   혼자 뻘짓하다가 해보게 됐다.

 

   자바로 외부파일 실행하는 코드. ㅡ.ㅡ..

Runtime rt = Runtime.getRuntime();

String exeFile = "실행할 파일의 경로";

System.out.println("exeFile: " + exeFile);

Process p;

    
try {

    p = rt.exec(exeFile);

    p.waitFor();

} catch (Exception e) {

    e.printStackTrace();

}

   이 방법의 단점은.. 파일을 로컬영역 안에서만 실행 테스트를 할 수 있다는 거다. 이걸 웹에 연결시키려고 했더니 다른 PC에서 실행 명령을 내리면 그 PC에서 파일이 실행되는 게 아니라, 서버쪽에서 실행 된다는 거..  ;;; 배포를 하고 그 주소로 경로를 써주면 실행이 되겠지..

   웹이랑 상관없이 사용한다면 괜찮다.

 

-------------------------------------------------------

   어떤 분의 요청으로 내용을 조금 추가한다.

   그 어떤 분의 요청이란, "웹에서 버튼을 클릭하면 서버 컴퓨터에 있는 프로그램이 실행되도록 해달라"라는 것.

   아주아주 초간단하게 만들어봤다.

   JSP페이지에 input text와 submit button을 만들어서 submit button을 클릭할 경우 execution.go를 타고 서블릿으로 향한다.

<form action="execution.go">

    <input type="text" name="fileName">

    <input type="submit" value="실행!">

</form>

 

서블릿에서는 다음과 같이 처리해준다.

import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class LocalFileExecutionServlet extends HttpServlet {

    @Override

    protected void service(HttpServletRequest req, HttpServletResponse res)

    throws ServletException, IOException {

        String fileName = req.getParameter("fileName");

        System.out.println("fileName : " + fileName);

        if (fileName != null && !fileName.isEmpty()) {

            // 파라미터로 받은 이름을 조건으로 실행할 프로그램을 선택, 아무것도 입력하지 않을 경우 계산기가 실행 됨.

            String directory = "C://Windows//System32//calc.exe";

            if (fileName.equals("계산기")) {

                directory = "C://Windows//System32//calc.exe";

            } else if (fileName.equals("메모장")) {

                directory = "C://Windows//System32//notepad.exe";

            } else if (fileName.equals("그림판")) {

                directory = "C://Windows//System32//mspaint.exe";

            }

            // 실제로 파일을 실행하는 구간------------------------------------

            Runtime rt = Runtime.getRuntime();

            System.out.println("directory: " + directory);

            Process p;

            try {

                p = rt.exec(directory);

                p.waitFor();

            } catch (Exception e) {

                e.printStackTrace();

            }

            // 실제로 파일을 실행하는 구간------------------------------------

        }

    }

}

 

   파라미터가 없는 경우에 대한 검증 처리 안함. <- jsp에서 자바스크립트로 할 수도 있고, 서블릿 단에서 처리할 수도 있음. 각자 알아서..

   이걸 실행할 경우, 실행한 클라이언트 측에서는 서버에서 프로그램이 실제로 실행했는지 알 수가 없다. 왜냐면, 원격조정이 아닌 이상 서버의 화면을 직접 볼 수가 없으니까.

 프로그램 실행 여부 확인을 위해서는 서블릿 단에서 성공/실패 시 리턴 페이지를 따로 만들어주는 것도 방법이다.

  근데 사실... 이렇게 웹서버 돌려가면서 하느니.. 원격조정이 제일 편하다. 뭐.. 요청하신 분의 사정이 있겠지만..;;

 

LocalFileTest.zip
0.01MB

 

 

=======================

=======================

=======================

 

 

 

출처: http://www.egovframe.go.kr/wiki/doku.php?id=egovframework:%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EB%AA%A8%EB%8B%88%ED%84%B0%EB%A7%81

요소기술 - 프로세스모니터링

개요

프로세스모니터링은 특정 프로세스가 기동 중인지 주기적으로 점검을 수행하고, 문제 발생시 해당 정보를 관리자에게 통보하는 기능을 제공한다.

설명

  • 프로세스모니터링은 프로세스모니터링을 등록하기 위한 목적으로 프로세스모니터링의 등록, 수정, 삭제, 조회, 목록조회의 기능을 수반한다.
  • 프로세스모니터링은 WINDOWS 및 UNIX 환경을 모두 지원 하며, globals.properties 파일의 Globals.OsType을 (Globals.OsType = UNIX 혹은 Globals.OsType = WINDOWS)로 설정한다.

① 프로세스모니터링목록조회 : 프로세스모니터링으로 정의된 정보를 최근 등록 순서대로 조회하고, 그 결과 목록을 화면에 반영한다. ② 프로세스모니터링등록 : 프로세스모니터링정보를 등록하고, 등록 결과를 조회한다. ③ 프로세스모니터링수정 : 기 등록된 프로세스모니터링정보의 항목들을 수정한다. ④ 프로세스모니터링삭제 : 기 등록된 프로세스모니터링정보를 삭제한다. ⑤ 프로세스모니터링조회 : 등록된 프로세스모니터링정보를 조회한다. ⑥ 프로세스모니터링로그목록조회 : 프로세스모니터링로그로 정의된 정보를 최근 등록 순서대로 조회하고, 그 결과 목록을 화면에 반영한다. ⑦ 프로세스모니터링조회 : 등록된 프로세스모니터링로그정보를 조회한다.

관련소스

유형대상소스명비고

Controller egovframework.com.utl.sys.prm.web.EgovProcessMonController.java 프로세스모니터링을 위한 컨트롤러 클래스
Service egovframework.com.utl.sys.prm.service.EgovProcessMonService.java 프로세스모니터링을 위한 서비스 인터페이스
ServiceImpl egovframework.com.utl.sys.prm.service.impl.EgovProcessMonServiceImpl.java 프로세스모니터링을 위한 서비스 구현 클래스
DAO egovframework.com.utl.sys.prm.service.impl.ProcessMonDAO.java 프로세스모니터링을 위한 데이터처리 클래스
Model egovframework.com.utl.sys.prm.service.ProcessMon.java 프로세스모니터링을 위한 Model 클래스
Model egovframework.com.utl.sys.prm.service.ProcessMonLog.java 프로세스모니터링로그정보를 위한 Model 클래스
JSP /WEB-INF/jsp/egovframework/utl/sys/prm/EgovProcessMonList.jsp 프로세스모니터링목록조회를 위한 jsp페이지
JSP /WEB-INF/jsp/egovframework/utl/sys/prm/EgovProcessMonRegist.jsp 프로세스모니터링 등록을 위한 jsp페이지
JSP /WEB-INF/jsp/egovframework/utl/sys/prm/EgovProcessMonUpdt.jsp 프로세스모니터링 수정을 위한 jsp페이지
JSP /WEB-INF/jsp/egovframework/utl/sys/prm/EgovProcessMonDetail.jsp 등록된 프로세스모니터링을 조회하기 위한 jsp페이지
JSP /WEB-INF/jsp/egovframework/utl/sys/prm/EgovProcessMonLogList.jsp 프로세스모니터링로그목록조회를 위한 jsp페이지
JSP /WEB-INF/jsp/egovframework/utl/sys/prm/EgovProcessMonLogDetail.jsp 등록된 프로세스모니터링로그을 조회하기 위한 jsp페이지
XML /egovframework/sqlmap/com/utl/sys/prm/EgovProcessMon_SQL_*.xml 프로세스모니터링 QUERY XML

클래스 다이어그램

 

관련테이블

테이블명테이블명(영문)비고

프로세스모니터링 COMTNPROCESSMON 프로세스모니터링정보를 관리하기 위한 속성정보를 정의하고, 관리한다.
프로세스모니터링로그정보 COMTNPROCESSMONLOGINFO 프로세스모니터링로그정보를 관리하기 위한 속성정보를 정의하고, 관리한다.

ID Generation

  • ID Generation Service를 활용하기 위해서 Sequence 저장테이블인 COMTECOPSEQ에 PROC_ID 항목을 추가한다.
  • ID Generation Service를 활용하기 위해서 Sequence 저장테이블인 COMTECOPSEQ에 PROL_ID 항목을 추가한다.

INSERT INTO COMTECOPSEQ VALUES('PROC_ID','0'); INSERT INTO COMTECOPSEQ VALUES('PROL_ID','0');  

프로퍼티 파일 설정globals.properties

시스템 환경에 대한 정보를 지정하기 위해서는 globals.properties 속성 파일에 추가 속성을 설정하여야 한다.

globals.properties에 관련된 내용은 요소기술 프로퍼티 및 명령어 쉘스크립트 부분을 참조한다.

UNIX인 경우

... Globals.OsType = UNIX ...

 

WINDOWS인 경우

... Globals.OsType = WINDOWS ...

스케줄러 등록

  • 프로세스모니터링 스케줄러를 등록하기 위해서 context-scheduling.xml 파일에 다음과 같이 등록한다.
<!-- 프로세스모니터링   -->
<bean
    id="processMntrng"
    class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
    <property name="targetObject" ref="egovProcessMonScheduling"/>
    <property name="targetMethod" value="monitorProcess"/>
    <property name="concurrent" value="false"/>
</bean>
<!-- 프로세스모니터링  트리거-->
<bean
    id="processMntrngTrigger"
    class="org.springframework.scheduling.quartz.SimpleTriggerBean">
    <property name="jobDetail" ref="processMntrng"/>
    <property name="startDelay" value="60000"/>
    <property name="repeatInterval" value="600000"/>
</bean>

 startDelay는 서버 시작후 몇초 뒤에 시작할지를 설정한다.(ms 단위 : 현재 1분)
 repeatInterval는 몇 초에 한번씩 실행될지를 설정한다.(ms 단위 : 현재 10분)
 
 <!-- 모니터링 스케줄러 -->
<bean
    id="mntrngScheduler"
    class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="triggers">
        <list>
            <ref bean="processMntrngTrigger"/>
        </list>
    </property>
</bean>

 

관련화면 및 수행메뉴얼

프로세스모니터링 목록조회

ActionURLController methodQueryID

조회 /utl/sys/prm/selectProcessMonList.do selectProcessMonList “ProcessMonDAO.selectProcessMonList”
조회 /utl/sys/prm/selectProcessMonList.do selectProcessMonList “ProcessMonDAO.selectProcessMonListCnt”

프로세스모니터링 목록은 페이지당 10건씩 조회되며 페이징은 10페이지씩 이루어진다. 검색조건은 상태,관리자명에 대해서 수행된다.

 

조회 : 기 등록된 프로세스모니터링의 목록을 조회한다.
등록 : 신규 프로세스모니터링를 등록하기 위해서는 상단의 등록 버튼을 통해서 프로세스모니터링 등록 화면으로 이동한다.
로그 : 프로세스모니터링로그 확인하기 위해서는 상단의 로그 버튼을 통해서 프로세스모니터링 로그목록 화면으로 이동한다.
이메일전송 : 프로세스모니터링 상태가 비정상일때 관리자에게 이메일을 발송한다.


프로세스모니터링 등록

ActionURLController methodQueryID

등록 /utl/sys/prm/addProcessMon.do insertProcessMon “ProcessMonDAO.insertProcessMon”

프로세스모니터링의 속성정보를 입력한 뒤 등록한다.

 

저장 : 신규 프로세스모니터링를 등록하기 위해서는 프로세스모니터링 속성을 입력한 뒤 상단의 저장 버튼을 통해서 프로세스모니터링를 등록한다.
목록 : 프로세스모니터링 목록조회 화면으로 이동한다.
프로세스명 : 공통컴퍼넌트가 설치된 서버의 프로세스명을 의미한다.


프로세스모니터링 수정

ActionURLController methodQueryID

수정 /utl/sys/prm/updateProcessMon updateProcessMon “ProcessMonDAO.updateProcessMon”

프로세스모니터링의 속성정보를 변경한 후 저장한다.

 

저장 : 기 등록된 프로세스모니터링 속성을 수정한 뒤 상단의 저장 버튼을 통해서 프로세스모니터링정보를 수정한다.
목록 : 프로세스모니터링 목록조회 화면으로 이동한다.


프로세스모니터링 상세조회

ActionURLController methodQueryID

상세조회 /utl/sys/prm/getProcessMon.do selectProcessMon “ProcessMonDAO.selectProcessMon”
삭제 /utl/sys/prm/deleteProcessMon.do deleteProcessMon “ProcessMonDAO.deleteProcessMon”

프로세스모니터링의 속성정보를 조회한다.

 

수정 : 기 등록된 프로세스모니터링 속성을 수정한 뒤 상단의 수정 버튼을 통해서 프로세스모니터링수정화면으로 이동한다.
삭제 : 기 등록된 프로세스모니터링정보를 삭제한다.
목록 : 프로세스모니터링 목록조회 화면으로 이동한다.


프로세스모니터링로그 목록조회

ActionURLController methodQueryID

조회 /utl/sys/prm/selectProcessMonLogList.do selectProcessMonLogList “ProcessMonDAO.selectProcessMonLogList”
조회 /utl/sys/prm/selectProcessMonLogList.do selectProcessMonLogList “ProcessMonDAO.selectProcessMonLogListCnt”

프로세스모니터링로그 목록은 페이지당 10건씩 조회되며 페이징은 10페이지씩 이루어진다. 검색조건은 상태,관리자명, 모니터링시각에 대해서 수행된다.

 

조회 : 기 등록된 프로세스모니터링로그의 목록을 조회한다.


프로세스모니터링로그 상세조회

ActionURLController methodQueryID

상세조회 /utl/sys/prm/getProcessMonLog.do selectProcessMonLog “ProcessMonDAO.selectProcessMonLog”

프로세스모니터링로그의 속성정보를 조회한다.

 

목록 : 프로세스모니터링로그 목록조회 화면으로 이동한다.

 

 

 

=======================

=======================

=======================

 

 

 

 

출처: http://okky.kr/article/56776

 

 

내가 띄운 프로세스 목록 얻어오기


자바에서요....

프로세스를 실행시킨후 내가 띄운 프로세스 목록을 얻어올수 있는 방법이 없나요?

내가 띄운 프로세스중에서 멈춘 프로세스를 다시 띄워주려고 하는데요.

어떤 방법으로 체크해야 하나요?

윈도우, 유닉스 각각 알고싶습니다.

방법좀 알려주세요.

 

간단한 서브 프로세스 관리 예제를 짜봤습니다.. 참고하세요

import java.lang.*;
import java.io.IOException;

public class ProcessTest {

    public static void main(String args[]) {
        Process p1 = null;
        try {
            p1 = Runtime.getRuntime().exec("sol.exe");
        } catch (IOException e) {
            System.out.println(" 1 프로세스 생성실패\n");
            return;
        }
        int i = 0;
        while (i < 100) {
            try {
                p1.exitValue();
                System.out.println(" 죽었음.. 다시 생성\n");
                p1 = Runtime.getRuntime().exec("sol.exe");
            } catch (IOException e) {
                System.out.println(" 2 프로세스 생성실패\n");
            } catch (IllegalThreadStateException ie) {
                // 아직 죽지 않음..
                System.out.println(" 안죽음\n");
            }
            try {
                Thread.sleep(60);
            } catch (InterruptedException ie) {
                System.out.println(" 인트럽트\n");
            }
            i++;
        }

    }
}

 

 

 

=======================

=======================

=======================

 

 

 

 

출처: http://lyb1495.tistory.com/11

 

1. 데몬(daemon) 이란?

주기적인 서비스 요청을 처리하기 위해서 커널상에 백그라운드 모드로 실행되는 프로세스로, 메모리 관리 방법에 따라 단독 데몬과 xinetd로 분리된다.

 

  • 단독데몬
    항상 백그라운드 모드로 실행되고 메모리를 상대적으로 많이 소비한다. 그러나 서비스(응답속도)가 빠르다. httpd와 같은 웹서비스 데몬이 대표적.
  • xinetd(슈퍼데몬)
    요청이 있을때마다 xinetd가 서비스를 싱행시켜주므로 메모리 소비가 적다. 그러나 단독데몬에 비해 상대적으로 서비스 속도가 느리다.

 

 

2. 간단한 자바 데몬 만들기

nohup을 이용해서 java를 실행시킨다.

 

터미널이 종료될 때(쉘이 종료될 때) 프로세스가 죽는 이유는 해당 프로세스가 쉘의 자식 프로세스 이기 때문이다. 따라서, 부모 프로세스가 죽을대 던지는 SIGHUP을 자식 프로세스가 받게 된다.

 

nohup은 부모 프로세스가 죽을때 자식 프로세스에게 SIGHUP을 던지지 않는 프로세스를 말한다.

 

$ nohup java 클래스명 & 

 

사용하기 편한 장점은 있으나, 문제는 중지를 시킬수 없다. 즉, 해당 프로세스 ID를 찾아내 kill하는 수 밖에 없다. 물론 파일 체크 기법, 소켓을 이용한 제어 방법등을 사용할 수 있지만 스스로 구현해야 하는 번거로움이 있다.

 

 

3. apache commons daemon 이용하기

Java는 UNIX의 시그널 처리를 할수 없기때문에, 중지 신호(TERM signal)를 처리하기 위해서는 따로 구현을 해야한다. 이런 번거로움을 해결하기 위해 자카르타의 하위 프로젝트중의 commons daemon을 이용한다. commons daemon은 중지 신호를 받으면 미리 지정된 메소드를 실행한다.

 

** 다운로드: http://commons.apache.org/daemon/

 

UNIX용 Jsvc와 윈도우용 Procrun 있다.

여기서는 Jsvc를 이용해보도록 하겠다.

 

 

commons daemon을 다운로드해 압축을 해제하면 위 그림과 같다.

commons-daemon.jar 파일은 Java프로젝트 lib폴더에 복사해둔다.

 

 

bin폴더의 압축파일을 해제하면 jsvc-src라는 폴더가 나온다.

폴더의 내용은 위와 같다.

commons daemon을 사용하기 위해서는 바로 여기서 jsvc를 빌드해줘야 한다.

빌드환경은 다음과 같다.(리눅스에서 빌드해야한다.)

 

  • GNU AutoConf(at least 2.53)
  • ANSI-C compliant compiler(GCC is good)
  • GNU Make
  • A Java Platform 2 compliant SDK

 

여기서부터는 ubuntu 8.10 환경에서 진행하도록 한다.

 

먼저 JDK가 설치되어 있지 않다면 JDK를 설치한다.

 

 $ sudo apt-get install sun-java6-jdk

 

JDK가 설치되는 경로는 /usr/lib/jvm/java-6-sun 이다.

 

gcc 및 make 가 설치되있지 않다면 아래 명령를 이용해 한방에 설치한다.

 

 $ sudo apt-get install build-essential

AutoConf가 설치되있지 않다면 AutoConf를 설치한다.

 

 $ sudo apt-get install autoconf

Jsvc를 빌드하는 방법은 다음과 같다.

 

  • support/buildconf.sh
  • ./configure --with-java=/usr/lib/jvm/java-6-sun
  • make

 

 

빌드가 성공적으로 이루어졌다면 위 그림과 같이 jsvc가 만들어진것을 확인할 수 있다. 이후 이 파일을 가지고 Java 데몬을 실행한다.

 

Java 데몬을 만들려면 org.apache.commons.daemon.Daemon 인터페이스의 init, start, stop, destory 메소드를 구현해야 한다.

 

샘플 코드는 아래와 같다

import org.apache.commons.daemon.Daemon;  
import org.apache.commons.daemon.DaemonContext;  
  
public class DaemonTest implements Daemon {  
  
    Thread t = null;  
      
    @Override  
    public void init(DaemonContext arg0) throws Exception {  
        System.err.println("daemonTest init");  
        t = new DaemonThread();  
    }  
  
    @Override  
    public void start() throws Exception {  
        System.err.println("daemonTest start");  
        t.start();  
    }  
  
    @Override  
    public void stop() throws Exception {  
        System.err.println("daemonTest stop");  
        t.interrupt();  
    }  
      
    @Override  
    public void destroy() {  
        System.err.println("daemonTest destroy");  
    }  
}  

 

public class DaemonThread extends Thread {  
  
    @Override  
    public void run() {  
        while( Thread.interrupted() ) {  
            System.err.println("run");  
            try {  
                Thread.sleep(5000);  
            } catch (InterruptedException e) {  
                Thread.currentThread().interrupt();  
                return;  
            }  
        }  
    }     
}  

 

init에서 초기화, start에서 처리할 작업을 별도의 쓰레드로 생성해서 실행한다. start 메소드 호출후 반드시 return 되어야 데몬이 시그널 처리를 제대로 할 수 있다.

stop, destroy 는 중지 신호가 오면 차례되로 호출된다.

 

이제 실행/중지 스크립트를 작성한다.

Jsvc를 싱행하는데 필요한것은 실행하는 계정(user), JAVA_HOME(-home), 프로세스ID 파일(-pidfile), 출력지정(-outfile, -errfile), 클래스파일(-cp) 등이 있다.

#!/bin/sh  
JAVA_HOME=/usr/lib/jvm/java-6-sun  
DAEMON_HOME=/home/lyb1495/commons-daemon-1.0.1/bin/jsvc-src  
DAEMON_USER=lyb1495  
DAEMONTEST_HOME=/home/lyb1495/workspace/Daemon  
PID_FILE=$DAEMONTEST_HOME/daemon_test.pid  
  
CLASSPATH=\  
$DAEMONTEST_HOME/bin:\  
$DAEMONTEST_HOME/lib/commons-daemon.jar  
  
case "$1" in  
  
    start)  
    #  
    # Start Daemon  
    #  
    $DAEMON_HOME/jsvc \  
    -user $DAEMON_USER \  
    -home $JAVA_HOME \  
    -wait 10 \  
    -pidfile $PID_FILE \  
-errfile '&1' \  
    -cp $CLASSPATH \  
    DaemonTest  
    #  
    # To get a verbose JVM  
    #-verbose \  
    # To get a debug of jsvc.  
    #-debug \  
    exit $?  
    ;;  
  
  stop)  
    #  
    # Stop PostMan  
    #  
    $DAEMON_HOME/jsvc \  
    -stop \  
    -pidfile $PID_FILE \  
    DaemonTest  
    exit $?  
    ;;  
#  
  *)  
    echo "Usage DaemonTest.sh start/stop"  
    exit 1;;  
esac  

 

이제 Java 데몬을 실행하기 위한 모든 준비를 마쳤다.

 

 

위에서 작성한 스크립트 파일을 이용해 Java 데몬을 실핸한다.

정상적으로 데몬이 시작된다면 PID_FILE에 지정한 파일이 생성된것을 확인할 수 있다.

 

 

데몬을 중지하려면 start 대신 stop을 입력으로 스크립트를 실행하면 된다.

 

 

 

=======================

=======================

=======================

 

 

반응형


관련글 더보기

댓글 영역