我在这里要完成的是通过Apache Commons Exec实例化第二个.jar的实例,而不是抛出第二个Java程序的主实例。
第二个.jar的作用基本上是将字节发送到stdout。这是启动此程序的代码。
private void runJar(PipedOutputStream output) throws IOException {
DefaultExecutor executor = new DefaultExecutor();
CommandLine commandLine;
String executeMe = "java -jar myjar.jar";
commandLine = CommandLine.parse(executeMe);
executor.setStreamHandler(new PumpStreamHandler(output, null));
executor.execute(commandLine, new DefaultExecuteResultHandler());
}
但到目前为止,我找不到一种方法来执行此操作而不阻止正常程序与库的正常流程,所以我作为一种解决方法做的是创建Thread,就像这样...
Thread t3 = new Thread() {
public void run() {
try {
runJar(output);
} catch (IOException e) {
e.printStackTrace();
}
}
};
t3.start();
我尝试通过cmd启动命令,一切正常,但在这种情况下,当我在Java中运行所有内容时,线程似乎在几秒钟后停止。
当我创建一个新线程时,我是否遗漏了某些内容,因此只要主程序可以存在,
更新
来自第一个.jar的可运行示例可以是此代码......
public class SecondApp {
public static void main(String[] args) throws ClassNotFoundException, IOException, InterruptedException {
File in = new File(args[0]);
try (InputStream input = new FileInputStream(in)) {
int bytesRead, CHUNK_SIZE = 4096;
byte[] data = new byte[CHUNK_SIZE];
while (true) {
bytesRead = input.read(data, 0, CHUNK_SIZE);
if (bytesRead > 0) {
System.out.write(data, 0, bytesRead);
System.out.flush();
} else if (bytesRead == -1) {
System.exit(0);
}
}
}
}
它基本上向stdout
吐出字节。第三个应用程序只是一个外部应用程序(ffmpeg),它通过PipedInputStream从第二个.jar接收这些字节,就像这样......
PipedOutputStream output = new PipedOutputStream();
PipedInputStream input = new PipedInputStream();
output.connect(input);
为了成功调试和了解Thread状态,我已经改变了同步的异步执行,现在我得到两个线程都处于RUNNABLE状态并且是ALIVE。
@Override
public void run() {
try {
DefaultExecutor executor = new DefaultExecutor();
CommandLine commandLine;
String executeMe = "java -jar myjar.jar";
commandLine = CommandLine.parse(executeMe);
executor.setStreamHandler(new PumpStreamHandler(output, null));
executor.execute(commandLine); //, new DefaultExecuteResultHandler());
} catch (ExecuteException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
正如@matt所说,可能是FFMPEG线程的输出没有被消耗的问题。
executor.setStreamHandler(
new PumpStreamHandler(
null, // stdout
null, // stderr
input)); // stdin
这是FFMPEG执行程序的前一行,现在由NullOutputStream(来自Apache Commons Exec的那个)更改。
executor.setStreamHandler(
new PumpStreamHandler(
new NullOutputStream(), // stdout
null, // stder
input)); // stdin
在这些更改之后,流似乎在几秒后停止,因此可能是@matt说的原因,流没有被消耗并且已经满了。为什么不使用NullOutputStream()?