的Runtime.exec()。WAITFOR()实际上不是等待(Runtime.exec(

2019-07-30 07:09发布

我有一个使用的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。

谢谢!

Answer 1:

另一种可能的方式来实现,这可能是捕捉过程的输出,并等待它完成。

例如:

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()

通过这样做,而循环,你强迫你的程序等待进程完成。



Answer 2:

您可以使用进程生成....

ProcessBuilder pb = new ProcessBuilder("java", "-jar", "/fielname.jar");
Process p = pb.start();
p.waitFor();


Answer 3:

你产生一个新的线程来处理过程的产卵? 如果是这样的原始程序将继续独立产生的进程,因此操作WAITFOR()将只对新的过程,而不是家长的工作。



Answer 4:

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);
 }


Answer 5:

我使用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.


文章来源: Runtime.exec().waitFor() not actually waiting for