Spring Boot从Runtime.getRuntime()开始.exec()一直等待,直到调用者进程终止

时间:2017-05-16 14:31:49

标签: java spring spring-mvc

我有两个Spring启动应用程序,一个叫做ProcessCenter,是一些移动和桌面应用程序的API,另一个叫做Watcher,负责让一切运行。

我的问题:

当Watcher看到ProcessCenter关闭时,他调用Runtime.getRuntime().exec( "java -jar ProcessCenter.jar" ),然后ProcessCenter开始启动,但冻结,我没有错误,没有记录,没有任何东西,只是保持冻结,直到Watcher关闭,然后它恢复启动并且工作得很好

帮助任何人?

1 个答案:

答案 0 :(得分:2)

基于JDK的Javadoc文档:"一些本机平台仅为标准输入和输出流提供有限的缓冲区大小,无法及时写入输入流或读取子流程的输出流可能导致要阻止的子进程,甚至是死锁。"

您可以按照本文了解如何正确实施外部流程调用,帮助您管理缓冲区 - > https://www.javaworld.com/article/2071275/core-java/when-runtime-exec---won-t.html?page=2

总而言之,您可以创建一个可以管理缓冲区限制的类,处理程序的输出,无论它有多大。一个例子:

import java.util.*;
import java.io.*;
class StreamGobbler extends Thread
{
    InputStream is;
    String type;
    OutputStream os;

    StreamGobbler(InputStream is, String type)
    {
        this(is, type, null);
    }
    StreamGobbler(InputStream is, String type, OutputStream redirect)
    {
        this.is = is;
        this.type = type;
        this.os = redirect;
    }

    public void run()
    {
        try
        {
            PrintWriter pw = null;
            if (os != null)
                pw = new PrintWriter(os);

            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);
            String line=null;
            while ( (line = br.readLine()) != null)
            {
                if (pw != null)
                    pw.println(line);
                System.out.println(type + ">" + line);    
            }
            if (pw != null)
                pw.flush();
        } catch (IOException ioe)
            {
            ioe.printStackTrace();  
            }
    }
}
public class GoodWinRedirect
{
    public static void main(String args[])
    {
        if (args.length < 1)
        {
            System.out.println("USAGE java GoodWinRedirect <outputfile>");
            System.exit(1);
        }

        try
        {            
            FileOutputStream fos = new FileOutputStream(args[0]);
            Runtime rt = Runtime.getRuntime();
            Process proc = rt.exec("java jecho 'Hello World'");
            // any error message?
            StreamGobbler errorGobbler = new 
                StreamGobbler(proc.getErrorStream(), "ERROR");            

            // any output?
            StreamGobbler outputGobbler = new 
                StreamGobbler(proc.getInputStream(), "OUTPUT", fos);

            // kick them off
            errorGobbler.start();
            outputGobbler.start();

            // any error???
            int exitVal = proc.waitFor();
            System.out.println("ExitValue: " + exitVal);
            fos.flush();
            fos.close();        
        } catch (Throwable t)
          {
            t.printStackTrace();
          }
    }
}