0

I want to know which jars are loaded by all the different running JVM's.

If I type "lsof -p $PID | grep jar >> /somefile" from the bash/command, it works beautifully! (replacing $PID with an actual process id). However, I would like to be able to do this from within a Java program. I would expect the following code to work but no file gets written:

public static void printCustomCommand(){
    String[] pids = {"pidof java"};
    String s;

    try {
        Process pidProcess = Runtime.getRuntime().exec("pidof java");
        BufferedReader br = new BufferedReader(new InputStreamReader(pidProcess.getInputStream()));
        pids = br.readLine().split(" ");

        for (String pid : pids){
            String cmd = "lsof -p " + pid + " | grep jar >> /somepath/mydumpfile";
            Process p;
            p = Runtime.getRuntime().exec(cmd);
            System.out.println(p.waitFor());
        }

        //pids = new String(bo).split(" ");
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

When I print the p.waitFor() command, it returns a 1 always, meaning according to the API documentation "something is incorrect". http://docs.oracle.com/javase/6/docs/api/java/lang/Process.html#waitFor%28%29

3
  • consider using ProcessBuilder instead Commented Jul 30, 2014 at 6:40
  • 1
    Read here too stackoverflow.com/questions/5928225/… Commented Jul 30, 2014 at 6:52
  • PeterMmm thank you very much! Combined with cartridgemeadow answer I managed to fix it :) Commented Jul 30, 2014 at 9:48

2 Answers 2

1

The issue is that Runtime.exec() does not understand shell concepts such as "|". Try this:

public static void printCustomCommand(){
    String[] pids = {"pidof java"};
    String s;

try {
    Process pidProcess = Runtime.getRuntime().exec("/bin/bash -c pidof java");
    BufferedReader br = new BufferedReader(new InputStreamReader(pidProcess.getInputStream()));
    pids = br.readLine().split(" ");

    for (String pid : pids){
        String cmd = "/bin/bash -c lsof -p " + pid + " | grep jar >> /somepath/mydumpfile";
        Process p;
        p = Runtime.getRuntime().exec(cmd);
        BufferedReader reader = 
        new BufferedReader(new InputStreamReader(p.getInputStream()));

    String line = "";
    while((line = reader.readLine()) != null) {
        System.out.print(line + "\n");
    }

    p.waitFor();  
    }

    //pids = new String(bo).split(" ");
} catch (IOException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
} catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
}

The problem is that exec runs a binary directly without invoking the shell. The "|" character is only recognized by the shell. The "-c" tells the shell to run a single command, and passes the entire command as the single argument.

Sign up to request clarification or add additional context in comments.

3 Comments

Looks like I'm on the right path now with your answer. Thank you! I had to change the first exec command back to "pidof java" or otherwise I'd got a nullpointer at br.readLine().split(" "); Now although I do get a lot of jars back, the command returns a different result to me (more than only jars, i.e. opendir: permission denied). I'm quite new to Linux, but I'm guessing it has something to do with other users working on the same server maybe?
What I mean with, I get different results is that I get different results in Java than in just a shell :)
Resolved it, my final solution would be to create a String array instead of one String. It was in PeterMmm's suggestion and works very nice.
1

Isn't that

Process pidProcess = Runtime.getRuntime().exec(new String[]{"pidof","java"});

?

And you cannot use pipes (|) in the exec method. The exec executes commands (executables) but pipes is part of the/a shell.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.