我有一些代码使用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
为10秒,作为一个简单的测试,正如预期的那样,A在运行10秒后才会返回。
我认为这可能是external.jar的某种线程问题,其中执行是从一件事移交给另一件事,但鉴于它直接从命令行工作,我希望看到相同的行为(从另一个java程序中调用时,可能是天真的。
我在Windows和Ubuntu上使用Java 6测试了这个。
谢谢!
答案 0 :(得分:6)
另一种可能的方法是捕获进程的输出并等待它完成。
例如:
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(),但是根据你正在执行的程序输出流,可能是:
通过执行此循环,您可以强制程序等待该过程完成。
答案 1 :(得分:1)
您可以使用Process Builder ....
ProcessBuilder pb = new ProcessBuilder("java", "-jar", "/fielname.jar");
Process p = pb.start();
p.waitFor();
答案 2 :(得分:0)
您是否正在产生一个新线程来处理该过程的产生?如果是这样,原始程序将继续独立于生成的进程运行,因此waitFor()仅适用于新进程而不是父进程。
答案 3 :(得分:-1)
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);
}
答案 4 :(得分:-1)
我使用进程使用控制台执行某些软件时遇到了同样的问题,我只是使用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.