Cloudera CDH/CDP 및 Hadoop EcoSystem, Semantic IoT등의 개발/운영 기술을 정리합니다. gooper@gooper.com로 문의 주세요.
Runtime.getRuntime().exe()로 문제가 발생 할만한 상황을 고려하여 만든소스임
String[] args = {"", "", ""};
// conf값을 확인해서 재설정함
args[0] = "/home/hadoop/bin/run.sh";
args[1] = "default";
args[2] = "a.txt";
StringBuilder sb = new StringBuilder();
for (String str : args) {
sb.append(str);
sb.append(" ");
}
후에 String[] result = Utils.runShell(sb)을 호출한다. (result[0]은 stdMsg, result[1]은 errorMsg가 넘어온다)
---------------------------------------Utils.java-----------------------------------------------------
(args는 shell명령어및 인자를 넣어서 runShell()을 실행시켜줌)
public static String[] runShell(StringBuilder args) throws Exception {
Process process = null;
boolean notTimeOver = true;
String[] result = new String[] { "", "" };
ProcessOutputThread stdMsgT=null;
ProcessOutputThread errMsgT=null;
// OS 종류 확인
String osName = System.getProperty("os.name");
try {
String[] cmd = null;
if (osName.toLowerCase().startsWith("window")) {
cmd = new String[] { "cmd.exe", "/y", "/c", sb.toString() };
} else {
cmd = new String[] { "/bin/sh", "-c", args.toString() };
}
// 콘솔 명령 실행
process = Runtime.getRuntime().exec(cmd);
// 실행 결과 확인 (에러)
StringBuffer stdMsg = new StringBuffer();
// 스레드로 inputStream 버퍼 비우기
stdMsgT = new ProcessOutputThread(process.getInputStream(), stdMsg);
stdMsgT.start();
StringBuffer errMsg = new StringBuffer();
// 스레드로 errorStream 버퍼 비우기
errMsgT = new ProcessOutputThread(process.getErrorStream(), errMsg);
errMsgT.start();
// 수행종료시까지 대기
while(true) {
if(! stdMsgT.isAlive() && ! errMsgT.isAlive()) {
notTimeOver = process.waitFor(30L, TimeUnit.MINUTES);
log.debug("Thread stdMsgT Status : "+stdMsgT.getState());
log.debug("Thread errMsgT Status : "+errMsgT.getState());
break;
}
}
log.debug("notTimeOver ==========================>" + notTimeOver);
// 실행결과
result[0] = stdMsg.toString();
result[1] = errMsg.toString();
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
if (process != null) {
IOUtils.closeQuietly(process.getOutputStream());
IOUtils.closeQuietly(process.getInputStream());
IOUtils.closeQuietly(process.getErrorStream());
process.destroy();
log.debug("process destoryed ==========================>");
}
}
args.delete(0, args.length());
args.setLength(0);
args = null;
return result;
}
--------------------------------ProcessOutputThread .java----------------------------------------------------------
//스레드로 inputStream 버퍼 비우기 위한 클래스 생성
public class ProcessOutputThread extends Thread {
private InputStream is;
private StringBuffer msg;
public ProcessOutputThread(InputStream is, StringBuffer msg) {
this.is = is;
this.msg = msg;
}
public void run() {
try {
msg.append(getStreamString(is));
} catch (Exception e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private String getStreamString(InputStream is) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(is));
StringBuffer out = new StringBuffer();
String stdLine;
while ((stdLine = reader.readLine()) != null) {
out.append(stdLine);
}
return out.toString();
} catch (Exception e) {
e.printStackTrace();
return "";
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}