Search code examples
javaprocessruntimeruntime.execjstack

Java Runtime.exec can not correctly execute JSTACK command


I'm attempting to execute jstack command using Runtime.exec but it seems there is an error but I can't find it out. In addition, I can execute the following command in CMD and it works fine:

C:\Users\bob>"C:\Program Files\Java\jdk1.6.0_18\bin\jstack" 5540 > d:\s.log

Test class full text:

package test;

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Test {

    public static void main(String[] args) {
        try {
            Process process = Runtime.getRuntime().exec("\"C:\\Program Files\\Java\\jdk1.6.0_18\\bin\\jstack\" 5540 > d:\\s.log");
            BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line = "";
            while ((line = input.readLine()) != null) {
                System.out.println(line);
            }
            int exitVal = process.waitFor();
            System.out.println("Exited with code '" + exitVal + "'");
        } catch (Exception e) {
            System.out.println("Error.");
        }
    }
}

Output:

Usage:

    jstack [-l] <pid>

        (to connect to running process)

Options:

    -l  long listing. Prints additional information about locks

    -h or -help to print this help message

Exited with code '1'

How can I solve this problem?

Thanks in advance.


Solution

  • the cause is your output redirection argument: > d:\\s.log jstack actually receives that bit as extra arguments, fails to parse it, and prints out the error.

    when you invoke the same command from the class (cmd.exe on windows) the shell itself recognizes the redirect command, strips it out of the command, and jstack only "sees" the pid argument.

    you have 2 options to fix this:

    1. dont call jstack.exe, call cmd.exe with an argument telling it to run jstack and redirect the output
    2. drop the redirection bit and write the output to file yourself