一段时间后,ProcessBuilder的Java应用程序启动被阻止

时间:2013-05-30 13:49:21

标签: java processbuilder

我正在开发一个包含3个按钮的Java桌面应用程序(我们称之为控制台):其中两个启动Win32应用程序;第三个应该启动一个可执行jar:

ProcessBuilder pb = new ProcessBuilder("java", "-jar", testDrivePath);
Process process = pb.start();

其中 testDrivePath 是jar的路径(类似于“C:\ Programs \ TestDrive.jar”)

TestDrive.jar应用程序正确启动,但一段时间后它会阻塞并无法进行任何操作。

如果我关闭控制台,TestDrive.jar又恢复工作了!

如果我单独启动TestDrive.jar(不从控制台调用它),一切都是正确的。

有人可以提供建议吗?

1 个答案:

答案 0 :(得分:3)

您可能需要从流程中读取输出流。你可以得到像这样的stdout和stderr流:

InputStream stdout = process.getInputStream();
InputStream stderr = process.getErrorStream();

您可以创建工作线程以异步读取这些流。

Thread threadOut = new Thread( new MyInputStreamSink( stdout, "out" ));
Thread threadErr = new Thread( new MyInputStreamSink( stderr, "err" ));

threadOut.setDaemon(true);
threadErr.setDaemon(true);
threadOut.setName( String.format("stdout reader" ));
threadErr.setName( String.format("stderr reader" ));

threadOut.start();
threadErr.start();

这是Runnable的一个实现,它使用流的输出。

private static class MyInputStreamSink implements Runnable {
    private InputStream m_in;
    private String m_streamName;

    MyInputStreamSink( InputStream in, String streamName ) {
        m_in = in;
        m_streamName = streamName;
    }

    @Override
    public void run() {
        BufferedReader reader = null;
        Writer writer = null;

        try {
            reader = new BufferedReader( new InputStreamReader( m_in ) );

            for ( String line = null; ((line = reader.readLine()) != null); ) {
                // TODO: Do something with the output, maybe.
            }
        } catch (IOException e) {
            s_logger.log( Level.SEVERE, "Unexpected I/O exception reading from process.", e );
        }
        finally {
            try {
                if ( null != reader ) reader.close();
            }
            catch ( java.io.IOException e ) {
                s_logger.log( Level.SEVERE, "Unexpected I/O exception closing a stream.", e );
            }
        }
    }
}