0

I think out two method to resolve this question but they can't reach the expectation .

  1. I use the 'Process' to exec "ps -ef"

    I can through this method to get all lines and I can filter them by my running command.But If I have many same command process.This isn't work.

  2. I use the JNA to get PID



    Field field = null;
    Integer pid = -1;
    try {
        Class clazz = Class.forName("java.lang.UNIXProcess");
        field = clazz.getDeclaredField("pid");
        field.setAccessible(true);
        pid = (Integer) field.get(process);
    } catch (Throwable e) {
        e.printStackTrace();
    }

This way only can get the PID of running window. It isn't the true PID of process.

what should I do?

Thanks!

4
  • 1
    There's a new API in Java 9 ProcessHandle which should work - assuming you have use Java 9 Commented Aug 16, 2018 at 1:39
  • You can call ps-ef after executing the java program. So with timestamp you can find out the new process just created. Or you can have param for your java program to make it unique. Or you can use ManagementFactory.getRuntimeMXBean().getName(). It is working fine on linux Commented Aug 16, 2018 at 1:42
  • @MadProgrammer That should be an answer. Commented Aug 16, 2018 at 1:47
  • Dupe stackoverflow.com/questions/4750470/… and that's reflection, not JNA, which is very different. Commented Aug 16, 2018 at 8:22

1 Answer 1

2

Java 9

Java 9 introduces a number "nice" changes, one is the inclusion of the native PID of a Process - see Process#pid for more details

import java.io.IOException;
import java.io.InputStream;

public class Test {

    public static void main(String[] args) throws IOException, InterruptedException {
        ProcessBuilder pb = new ProcessBuilder("/Applications/Xcode.app/Contents/MacOS/Xcode");
        pb.redirectErrorStream(true);
        Process p = pb.start();
        // Yes, I'm a bad developer, but I just want to demonstrate
        // the use of the PID method :/
        new Thread(new Consumer(p.getInputStream())).start();
        System.out.println("PID = " + p.pid());
        p.waitFor();
        System.out.println("Exit with " + p.exitValue());
    }

    public static class Consumer implements Runnable {
        private InputStream is;

        public Consumer(InputStream is) {
            this.is = is;
        }

        @Override
        public void run() {
            try {
                int value = -1;
                while ((value = is.read()) != -1) {
                    // I'm ignoring it for brevity
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

}

You can also obtain a reference to the ProcessHandle for the Process via the Process#toHandle method, which is kind of nice

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

8 Comments

When I use Process in linux, It will hava two PID. ex: 11102 11104
11102 is sh -c cd /usr/lib/projecthouse/github_project_1/target && java -jar demo-0.0.1-
11104 is the real PID (java -jar demo-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod)
but process.pid() always get the first PID ex: 11102 ,what should i do
So - don’t use a shell script, execute java directly
|

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.