Skip to content

Instantly share code, notes, and snippets.

@sakamotodesu
Created March 28, 2012 03:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save sakamotodesu/2223469 to your computer and use it in GitHub Desktop.
Save sakamotodesu/2223469 to your computer and use it in GitHub Desktop.
apache commons exec "write end dead" sample
package com.test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecuteResultHandler;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.ExecuteException;
import org.apache.commons.exec.PumpStreamHandler;
public class ApacheCommonExec {
public static void main(String[] args) {
// コマンドを作成
CommandLine commandLine = new CommandLine("ping");
commandLine.addArgument("/n");
commandLine.addArgument("5");
commandLine.addArguments("/w 1000");
commandLine.addArgument("127.0.0.1");
// Executorを作成
DefaultExecutor executor = new DefaultExecutor();
try {
//プロセスの出力をPipedOutputStreamに吐かせる
PipedOutputStream output = new PipedOutputStream();
PumpStreamHandler streamHandler = new PumpStreamHandler(output);
executor.setStreamHandler(streamHandler);
// 正常終了の場合に返される値
executor.setExitValue(0);
// 非同期で実行
DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
executor.execute(commandLine, resultHandler);
PipedInputStream input = new PipedInputStream(output);
BufferedReader br = new BufferedReader(new InputStreamReader(input));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
output.close();
input.close();
} catch (ExecuteException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
@cb372
Copy link

cb372 commented Mar 28, 2012

ここでApache Commons ExecもPipedInputStreamも悪い:

  • Commons Execが、ストリームを閉じないでスレッドを終了させてしまう。
  • PipedOutputStreamを書いているスレッドが死ねば、つながっているPipedInputStreamが例外を投げるという微妙な仕様がある。

PipedOutputStreamのJavadocより:

"A pipe is said to be broken if a thread that was providing data bytes to the connected piped output stream is no longer alive."

PipedOutputStream#read()のJavadocより:

"Throws:
IOException - if the pipe is unconnected, broken, closed, or if an I/O error occurs.

@sakamotodesu
Copy link
Author

ありがとう!

やっぱapache common execの採用は見送った方がよさそうだね。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment