Example of redirecting standard out and err of a spawned Process.

The inability to capture a Java thread dump when a JVM is run detached from a terminal makes troubleshooting issues difficult. I have spent a good deal of time trying to force a Java thread dump through the swawned application code but found it is not possible though the API -- when a JVM receives a SIGQUIT signal it will produce a thread dump to the Unix-level standard out (file descriptor 1). The only way to capture the dump is to redirect standard out when the Port Monitor process is launched. The parent process is doing a Runtime.getRuntime().exec() to spawn a child process. In order to capture the OS-level standard out and error the sub-process needs to be launched similar to this:

            Process process = Runtime.getRuntime().exec(command);

            ProcessLogger errorStream = new ProcessLogger(process
                    .getErrorStream()new FileOutputStream("stderr.log"),
                    "stderr.log");

            ProcessLogger outputStream = new ProcessLogger(process
                    .getInputStream()new FileOutputStream("stdout.log"),
                    "stdout.log");

The ProcessLogger class just takes the input stream and writes it out to a file. It could just as easily write out to a log4j Appender but I wanted the sample code as simple as possible.

I created a jar name process.jar with three class files and included the source for your own enjoyment.

Run it on a *nix box::
java ParentProcess
ParentProcess exec's SubProcess and redirects SubProcess' standout output and error streams to files "stdout.log" and "stderr.log" using a simple Logger. The SubProcess redirects it's System.out and System.err to the file "application.log" and recursively calls a method, outputting a count once per second.
do a ps -ef | grep ProcessWorker and note PID. Next do a kill -QUIT <pid> and a Java thread dump should output to the "stdout.log" file.