Enrico
Enrico

Reputation: 31

Java application lauched with ProcessBuilder blocked after some time

I am developing a Java desktop application (let's call it console) containing 3 buttons: two of them launch a Win32 applications; the third should launch an executable jar:

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

where testDrivePath is the path to the jar (something like "C:\Programs\TestDrive.jar")

The TestDrive.jar application launches correctly, but after some time it blocks and is not able to make any operation.

If I close the console, the TestDrive.jar is back working!

If I launch the TestDrive.jar as a stand alone (without invoking it from the console), everything is correct.

Can anyone advise?

Upvotes: 3

Views: 3019

Answers (1)

Andy Thomas
Andy Thomas

Reputation: 86509

You likely need to read the output stream from the process. You can get stdout and stderr streams like this:

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

You may create worker threads to read from those streams asynchronously.

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

Here's an implementation of a Runnable that consumes the output from a stream.

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

Upvotes: 4

Related Questions