티스토리 뷰
자바로 외부 프로그램 실행 시키는 방법중에 ProcessBuilder 에 대해서 간단하게 소개 하려고 한다.
자바에서는 외부 프로그램 실행 시 출력 내용을 바로 확인 할 수 없고 버퍼에 저장 후 출력하는 형식으로
확인 하여야 한다.
JDK 1.4 버전 이하에서는 exec() 메소드를 이용하여 외부 프로그램을 실행 시킬 수 있고
JDK 1.5 버전 이상에서는 ProcessBuilder 객체를 이용하여 외부 프로그램을 실행 시킬 수 있다.
Process 객체 생성 후 실행 할 커맨드를 다음과 같이 쪼개어 인자값으로 넣어 주어야 한다.
Process process = new ProcessBuilder("cmd", "dir", "/w").start();
위와같이 표현 한다면 cmd 커맨드 창을 실행 후 dir /w 명령어를 실행 한다는 의미 이다.
혹은 다음과 같이 배열을 이용하여 표현 할 수도 있다.
String[] cmd = new String[] {"cmd", "dir", "/w"};
Process process = new ProcessBuilder(cmd).start();
이렇게 실행 한 결과를 버퍼에 저장 후 표준 출력을 화면에 표시 하여야 하는데 다음과 같이 표현 할 수 있다.
BufferedReader stdOut = new BufferedReader( new InputStreamReader(process.getInputStream()) );
// 표준출력 상태를 출력
while( (str = stdOut.readLine()) != null ) {
System.out.println(str);
}
InputStreamReader 객체를 통하여 위 process 객체에서 출력된 스트림을 입력 받아 버퍼에 저장 후
while 문을 통하여 버퍼에 저장 된 내용을 표시하여 주는 것이다.
하나의 예로 웹 브라우저를 띄운 후 원하는 페이지로 이동 하는것을 예를 든다면 다음과 같이 할 수 있다.
String addr = "http://www.naver.com";
Process process = null;
String[] cmd = new String[] {"rundll32", "url.dll", "FileProtocolHandler", addr};
String str = null;
try {
// 프로세스 빌더를 통하여 외부 프로그램 실행
process = new ProcessBuilder(cmd).start();
// 외부 프로그램의 표준출력 상태 버퍼에 저장
BufferedReader stdOut = new BufferedReader( new InputStreamReader(process.getInputStream()) );
// 표준출력 상태를 출력
while( (str = stdOut.readLine()) != null ) {
System.out.println(str);
}
} catch (IOException e) {
e.printStackTrace();
}
이렇게 하면 rundll32를 통하여 웹 브라우저 실행 후 네이버로 이동된다.
출처: http://yangyag.tistory.com/55 [Hello Brother!]
일단 출처 대로하면 잘 웹 브라우저 실행 후 네이버로 잘 이동 된다.
우리는 더 나가서 리턴값을 받고 그에 따라서 다른 액션을 취하고 싶다. 예를들어 특정 배치를 실행했을때 정상 리턴값(예: 0) 일경우 행위와 비 정상처리되었을때 처리를 다르게 하고 싶을때 사용한다.
별거 아닌거 같아 보일 수 있지만 상당히 중요한 부분이 될 수 있다.
함께 연구해 보자.
일단 위에는 안나왔는데 프로세스가 끝날 까지 기다리는 waitFor 메소드를 사용할 수 있다.
또한 자바 Process 클래스에는 exitValue()라는 메소드를 제공한다. 우선 자바 api 를 살펴보면
waitFor
public abstract int waitFor() throws InterruptedException
Causes the current thread to wait, if necessary, until the process represented by thisProcess
object has terminated. This method returns immediately if the subprocess has already terminated. If the subprocess has not yet terminated, the calling thread will be blocked until the subprocess exits.- Returns:
- the exit value of the subprocess represented by this
Process
object. By convention, the value0
indicates normal termination. - Throws:
InterruptedException
- if the current thread is interrupted by another thread while it is waiting, then the wait is ended and anInterruptedException
is thrown.
exitValue
public abstract int exitValue()
Returns the exit value for the subprocess.- Returns:
- the exit value of the subprocess represented by this
Process
object. By convention, the value0
indicates normal termination. - Throws:
IllegalThreadStateException
- if the subprocess represented by thisProcess
object has not yet terminated
위와 같다.
배치파일을 실행해서 위의 메소드 exitValue()를 써봤는데 배치파일에 오류가 나도 성공의 의미인 0 이 자꾸 찍혔다.
추측 하건데 exitValue 는 배치 실행에 에러가 없으면 0 으로 판단하는거 같았다. 배치 실행시 에러가 발생했지만 의도적으로 리턴값을 0으로 하지 않으면 특이사항이 없으니 0으로 판단하는거 같았다.
그래서 배치에서 에러가 발생했을때 의도적으로 에러코드를 잡아서 리턴해줘야 겠다고 생각했다.
여러 경로로 알아본 결과
exit /b %ERRORLEVEL%
이렇게 배치 명령 다음줄에 넣어주면 exitValue 메소드에서 에러코드를 얻을 수 있었다.
그래서 결론은 아래 처럼 구현했다.
Process process = new ProcessBuilder(src).start();
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
while((line=br.readLine())!=null){
logger.debug("line = "+line);
}
process.waitFor();
exitValue=process.exitValue();
이렇게 해서 exitValue를 사용하면 되겠다.
'자바(Java)' 카테고리의 다른 글
addBatch executeBatch (0) | 2017.08.31 |
---|---|
[Tomcat] 톰캣 startup bat 재시작 배치파일 만들기 (0) | 2017.08.08 |
자바 암호화 - javax.crypto.BadPaddingException: Given final block not properly padded (0) | 2017.07.18 |
자바 암호화 - java.security.InvalidKeyException: Parameters missing (0) | 2017.07.18 |
자바 암호화 - java encrypt (0) | 2017.07.18 |
- Total
- Today
- Yesterday
- 파싱
- 문자열
- webix
- XE
- JDBC
- 라이믹스 모듈
- 플러터
- php
- esql
- KG
- ocjap
- 포인터
- XE3
- xe애드온
- C
- Python
- xe addon
- MySQL
- proc
- 프로씨
- 스크래핑
- C언어
- 자바 smtp
- 오라클
- 이클립스
- 파이썬
- ocajp
- 자바
- 인포믹스
- EC
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |