1

I need to get the PID of a process which is launched via Java's Runtime.getRuntime().exec() command.

I know how to do it in JNA. But I really would like to do it with JNI and create my own libraries. Does anyone know how to do it?

import java.lang.reflect.Field;

class GetPid
{
    public native int getPid( long procHandle);

    static
    {
        System.loadLibrary("getpid");
    }

    public static void main(String args[])
    {
        try {

          Process process = Runtime.getRuntime().exec( "calc");
          Field f = process.getClass().getDeclaredField( "handle");
          f.setAccessible( true);
          long procHandle = f.getLong( process);

          System.out.println( "prochandle: " + procHandle + ", pid: " + new GetPid().getPid( procHandle));

        } catch( Exception e) {
          e.printStackTrace();
        }

    }
}

But what's the C part supposed to look like?

JNIEXPORT jint JNICALL
Java_GetPid_getPid(JNIEnv *env, jobject obj, jlong handle)
{
    ...

    return ???;
}

It would be great if someone could help me. I mainly seek the Windows solution, since you can get the PID for Linux from the Process field, but I wouldn't mind if someone could show me how to do this in Linux / Solaris as well.

Thank you very much in advance!

Roland
  • 18,114
  • 12
  • 62
  • 93
  • @Jermaine Xu: I don't need the PID of the current Java process, but the one from the one executed via exec(). In other words: I need to get the PID using the "jlong handle" parameter. I need it for Windows. Platform independency would be good, but I guess it's complicated. – Roland Mar 10 '13 at 07:59
  • @Taky: Thank you, I've been there already. That's not what I'm looking for. I don't need the PID of the Java process, and the suggested JNA is a bit heavy for this. – Roland Mar 10 '13 at 08:01

2 Answers2

2

Got it. It was as simple as using:

#define WINVER 0x0501
#define _WIN32_WINNT 0x0501

and

JNIEXPORT jint JNICALL
Java_GetPid_getPid(JNIEnv *env, jobject obj, jlong handle)
{
  return GetProcessId((HANDLE) handle);
}

Thanks to all who tried to help :-)

Roland
  • 18,114
  • 12
  • 62
  • 93
1

I found this page that might be useful - http://golesny.de/p/code/javagetpid. It gives code for extracting an external processes PID on various platforms ... in a couple of ways.

In summary:

  • You can use RuntimeMXBean to list all running processes, and then use pattern matching to pick out one that matches the name of the process whose PID you are trying to find. (But the gotcha is that process names are not unique ...)

  • On Linux / UNIX you can fish the PID out of the XxxProcess object using reflection.

  • On Windows you have to use JNA to get the PID. Some code to do this is on the linked page.


If I was doing this, I think I'd take a different approach. I'd see if it was possible to get the external command (or a wrapper / launcher) to figured out what the PID is, and then write it somewhere that the parent JVM can read it.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • Thank you, been there already. Pattern matching is out of question because I launch multiple processes with the same name. And the code above uses JNA, but I can't use that. Actually all I need is a way to get the PID from a numeric handle instead of a HWND. Or to be more precisely a way to get a HWND from a handle's number, since I could use GetWindowThreadProcessId to get the PID. – Roland Mar 10 '13 at 08:30
  • Do you mean "cannot use JNA" or "do not want to use JNA"? And in the former case, why not? – Stephen C Mar 10 '13 at 08:35
  • Well that is sad. Sounds like you'll have to code up your own JNI version then ... or hope that the RuntimeMXBean version works well enough for you. – Stephen C Mar 10 '13 at 12:22
  • RuntimeMXBean only gets the handle/pid of the java process. But I need the one from the processes which I spawn via Runtime's exec() method. – Roland Mar 11 '13 at 05:53
  • So it is JNI for you. If the company policy requires you to waste your / their time reinventing open source libraries ... that's their problem. – Stephen C Mar 11 '13 at 10:42