我有一个使用的Runtime.exec()来运行一个外部.jar(建为的IzPack安装程序)的一些代码。
如果我运行从像这样的命令行这external.jar:
java -jar external.jar
然后直到应用程序完成的命令提示符不会返回控制。 但是,如果我从一些Java类中external.jar运行,使用:
Process p = Runtime.getRuntime().exec("java -jar external.jar");
int exitCode = p.waitFor();
System.out.println("Process p returned: " + exitCode);
然后p
返回几乎立即与成功代码0
,尽管有尚未完成执行external.jar(我已经通过也试过这种ProcessBuilder
外部文件执行的路线)。
为什么它等待命令行返回,而不是在从另一个Java程序中执行?
我还设置了3罐,A,B和C,其中A呼叫B它调用C(使用Runtime.exec()
其中C Thread.sleep
S代表10秒,作为一个简单的测试,并且如预期,A不返回直到晚上10秒钟,这两点后运行。
我想这可能是某种与external.jar一个线程问题,即执行正从一件事情切换到另一个的,但考虑到它直接在命令行那种我期望看到相同的行为(或许天真)当从另一个Java程序中调用。
我已经与Java 6的测试,这在Windows和Ubuntu。
谢谢!
另一种可能的方式来实现,这可能是捕捉过程的输出,并等待它完成。
例如:
Process tr = Runtime.getRuntime().exec( new String[]{"wkhtmltopdf",mainPage,mainPagePDF});
BufferedReader stdOut=new BufferedReader(new InputStreamReader(tr.getInputStream()));
String s;
while((s=stdOut.readLine())!=null){
//nothing or print
}
通常,输出流是tr.getInputStream(),但可以根据正在执行的处理的输出流migh是该程序:
- tr.getInputStream()
- tr.getErrorStream()
- tr.getOutputStream()
通过这样做,而循环,你强迫你的程序等待进程完成。
您可以使用进程生成....
ProcessBuilder pb = new ProcessBuilder("java", "-jar", "/fielname.jar");
Process p = pb.start();
p.waitFor();
你产生一个新的线程来处理过程的产卵? 如果是这样的原始程序将继续独立产生的进程,因此操作WAITFOR()将只对新的过程,而不是家长的工作。
Process.waitFor()
是没有用的一些原生系统命令。
你需要得到流程的输出,以确定是否返回它。
我写了一个示例代码为您
/**
*
* @param cmdarray command and parameter of System call
* @param dir the directory execute system call
* @param returnImmediately true indicate return after system call immediately;
* false otherwise.
* if set true, the returned call result does not have reference value
* @return the return code of system call , default is -1
*/
public static int systemCall(String[] cmdarray,File dir,boolean returnImmediately)
{
int result = -1;
try {
Process p = Runtime.getRuntime().exec(cmdarray,null,dir);
if(!returnImmediately)
{
java.io.InputStream stdin = p.getInputStream();
java.io.InputStreamReader isr = new java.io.InputStreamReader(stdin);
java.io.BufferedReader br = new java.io.BufferedReader(isr);
String line = null;
while ( (line = br.readLine()) != null)
System.out.println(line);
}
try{result = p.exitValue();}
catch(Exception ie){;}
} catch (IOException e) {
e.printStackTrace();}
return result;
}
public static void main(String[] argc){
String[] cmdarray = {"jar","cvf","s2.jar","*"};
File dir = new File("D:\\src\\struts-2.3.1");
int k = systemCall(cmdarray,dir,true);
System.out.println("k="+k);
}
我使用PROCESSS使用控制台执行某些软件有同样的问题,我只是解决了它使用process.waitFor()
对我来说,它的工作完美。
try{
Process tr = Runtime.getRuntime().exec( new String[]{ "wkhtmltopdf",frontPage,frontPagePDF});
tr.waitFor();
} catch (Exception ex) {
EverLogger.logEntry("Error al pasar a PDF la portada", "error", "activity");
return;
}
some more code here.