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!

Community
  • 1
  • 1
JinxLbj
  • 3
  • 2
  • 1
    There's a new API in Java 9 [`ProcessHandle`](https://docs.oracle.com/javase/9/docs/api/java/lang/ProcessHandle.html) which should work - assuming you have use Java 9 – MadProgrammer Aug 16 '18 at 01: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 – Nghia Do Aug 16 '18 at 01:42
  • @MadProgrammer That should be an answer. – Andreas Aug 16 '18 at 01:47
  • Dupe https://stackoverflow.com/questions/4750470/how-to-get-pid-of-process-ive-just-started-within-java-program and that's reflection, not JNA, which is very different. – dave_thompson_085 Aug 16 '18 at 08:22

1 Answers1

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

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • When I use Process in linux, It will hava two PID. ex: 11102 11104 – JinxLbj Aug 16 '18 at 03:21
  • 11102 is sh -c cd /usr/lib/projecthouse/github_project_1/target && java -jar demo-0.0.1- – JinxLbj Aug 16 '18 at 03:22
  • 11104 is the real PID (java -jar demo-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod) – JinxLbj Aug 16 '18 at 03:23
  • but process.pid() always get the first PID ex: 11102 ,what should i do – JinxLbj Aug 16 '18 at 03:23
  • So - don’t use a shell script, execute java directly – MadProgrammer Aug 16 '18 at 03:24
  • Also, if you take the time to read the [JavaDocs](https://docs.oracle.com/javase/9/docs/api/java/lang/ProcessHandle.html) you would find that `ProcessHandle` provides a `children` method - I'd be looking at that and seeing what it does – MadProgrammer Aug 16 '18 at 03:46
  • sorry,i can't get your mean.Is it mean i can't use RunTime to exec it? – JinxLbj Aug 16 '18 at 03:47
  • What does `Runtime.exec` return? You don't seem to be taking the time to read the links I keep throwing at you - also the last sentence in the answer even shows you how to get a `ProcessHandle` from a `Process` - this all assume you're using Java 9 of course – MadProgrammer Aug 16 '18 at 03:55