¿Cómo puede un programa de Java obtener su propio proceso de IDENTIFICACIÓN?

StackOverflow https://stackoverflow.com/questions/35842

  •  09-06-2019
  •  | 
  •  

Pregunta

¿Cómo puedo obtener el id de mi proceso Java?

Sé que hay varios dependientes de la plataforma, hacks, pero yo preferiría una solución más genérica.

¿Fue útil?

Solución

No existe ninguna plataforma independiente de la forma en que se puede garantizar que el trabajo en todas las implementaciones de jvm.ManagementFactory.getRuntimeMXBean().getName() parece que el mejor (el más cercano) de la solución.Es corto, y probablemente obras en cada aplicación en uso de ancho.

En linux+windows devuelve un valor como 12345@hostname (12345 siendo el identificador de proceso).Tenga en cuenta sin embargo que de acuerdo a la documentación, no hay garantías acerca de este valor:

Devuelve el nombre representa la ejecución de la máquina virtual de Java.El devuelve el nombre de la cadena puede ser cualquier cadena arbitraria y virtual de Java máquina de aplicación puede elegir para integrar específico de la plataforma útil información en el devuelve el nombre de la cadena.Cada máquina virtual en ejecución podría tener un nombre diferente.

En Java 9 el nuevo proceso de API puede ser utilizado:

long pid = ProcessHandle.current().pid();

Otros consejos

Usted podría utilizar JNA.Lamentablemente no es común JNA de la API para obtener la corriente ID de proceso, pero cada plataforma es bastante simple:

Windows

Asegúrese de que usted tiene jna-platform.jar entonces:

int pid = Kernel32.INSTANCE.GetCurrentProcessId();

Unix

Declarar:

private interface CLibrary extends Library {
    CLibrary INSTANCE = (CLibrary) Native.loadLibrary("c", CLibrary.class);   
    int getpid ();
}

Entonces:

int pid = CLibrary.INSTANCE.getpid();

Java 9

En Java 9 la nueva proceso de API puede ser utilizado para obtener la corriente ID de proceso.Primero coges un identificador del proceso actual, a continuación, consulta el PID:

long pid = ProcessHandle.current().pid();

He aquí una puerta trasera método que podría no funciona con todas las máquinas virtuales, pero debería funcionar en linux y windows (ejemplo original aquí):

java.lang.management.RuntimeMXBean runtime = 
    java.lang.management.ManagementFactory.getRuntimeMXBean();
java.lang.reflect.Field jvm = runtime.getClass().getDeclaredField("jvm");
jvm.setAccessible(true);
sun.management.VMManagement mgmt =  
    (sun.management.VMManagement) jvm.get(runtime);
java.lang.reflect.Method pid_method =  
    mgmt.getClass().getDeclaredMethod("getProcessId");
pid_method.setAccessible(true);

int pid = (Integer) pid_method.invoke(mgmt);

Trate de Sigar .muy extensa Api.Apache 2 de la licencia.

    private Sigar sigar;

    public synchronized Sigar getSigar() {
        if (sigar == null) {
            sigar = new Sigar();
        }
        return sigar;
    }

    public synchronized void forceRelease() {
        if (sigar != null) {
            sigar.close();
            sigar = null;
        }
    }

    public long getPid() {
        return getSigar().getPid();
    }

El siguiente método intenta extraer el PID de java.lang.management.ManagementFactory:

private static String getProcessId(final String fallback) {
    // Note: may fail in some JVM implementations
    // therefore fallback has to be provided

    // something like '<pid>@<hostname>', at least in SUN / Oracle JVMs
    final String jvmName = ManagementFactory.getRuntimeMXBean().getName();
    final int index = jvmName.indexOf('@');

    if (index < 1) {
        // part before '@' empty (index = 0) / '@' not found (index = -1)
        return fallback;
    }

    try {
        return Long.toString(Long.parseLong(jvmName.substring(0, index)));
    } catch (NumberFormatException e) {
        // ignore
    }
    return fallback;
}

Solo llame getProcessId("<PID>"), por ejemplo.

Para los mayores de la JVM, en linux...

private static String getPid() throws IOException {
    byte[] bo = new byte[256];
    InputStream is = new FileInputStream("/proc/self/stat");
    is.read(bo);
    for (int i = 0; i < bo.length; i++) {
        if ((bo[i] < '0') || (bo[i] > '9')) {
            return new String(bo, 0, i);
        }
    }
    return "-1";
}

Usted puede comprobar fuera de mi proyecto: JavaSysMon en GitHub.Se proporciona el id de proceso y un montón de otras cosas (uso de CPU, uso de memoria) de la cruz-plataforma (en la actualidad Windows, Mac OSX, Linux y Solaris)

Desde Java 9 hay un método de Proceso.getPid (), que devuelve el nativo de IDENTIFICACIÓN de un proceso:

public abstract class Process {

    ...

    public long getPid();
}

Para obtener el IDENTIFICADOR de proceso del actual proceso Java se puede utilizar el ProcessHandle interfaz:

System.out.println(ProcessHandle.current().pid());

En Scala:

import sys.process._
val pid: Long = Seq("sh", "-c", "echo $PPID").!!.trim.toLong

Esto debe darle una solución en sistemas Unix hasta Java 9 será lanzado.(Lo sé, la pregunta era acerca de Java, pero ya que no hay equivalente pregunta para Scala, quería dejar esta para Scala, los usuarios que puedan tropezar en la misma pregunta.)

La integridad no es un contenedor en La Primavera De Arranque para el

String jvmName = ManagementFactory.getRuntimeMXBean().getName();
return jvmName.split("@")[0];

solución.Si un entero es necesario, entonces esto se puede resumir a la línea:

int pid = Integer.parseInt(ManagementFactory.getRuntimeMXBean().getName().split("@")[0]);

Si alguien usa la Primavera de arranque ya que él/ella podría usar org.springframework.el arranque.ApplicationPid

ApplicationPid pid = new ApplicationPid();
pid.toString();

El método toString() imprime el pid o '???'.

Advertencias el uso de la ManagementFactory se discuten en otras respuestas ya.

public static long getPID() {
    String processName = java.lang.management.ManagementFactory.getRuntimeMXBean().getName();
    if (processName != null && processName.length() > 0) {
        try {
            return Long.parseLong(processName.split("@")[0]);
        }
        catch (Exception e) {
            return 0;
        }
    }

    return 0;
}

La última que he encontrado es que hay un el sistema de propiedad llama sun.java.launcher.pid que está disponible al menos en linux.Mi plan es usar eso y si no se encuentra el uso de la JMX bean.

java.lang.management.ManagementFactory.getRuntimeMXBean().getName().split("@")[0]

Depende de dónde usted está buscando la información.

Si usted está buscando para la información de la consola puede utilizar la jps comando.El comando le da una salida similar a Unix el comando ps y viene con el JDK, ya que creo 1.5

Si usted está mirando desde el proceso de la RuntimeMXBean (como dijo por Wouter Coekaerts) es probablemente su mejor opción.La salida de getName() en Windows utilizando Sun JDK 1.6 u7 es en la forma [IDENTIFICADOR_DE_PROCESO]@[NOMBREDEEQUIPO].Usted podría, sin embargo, intentar ejecutar jps y analizar el resultado de que:

String jps = [JDK HOME] + "\\bin\\jps.exe";
Process p = Runtime.getRuntime().exec(jps);

Si se ejecuta sin opciones de la salida debe ser el identificador del proceso seguido por el nombre.

Basado en Ashwin Jayaprakash del respuesta (+1) acerca de la licencia de Apache 2.0 SIGAR, aquí es cómo yo lo uso sólo para conseguir el PID del proceso actual:

import org.hyperic.sigar.Sigar;

Sigar sigar = new Sigar();
long pid = sigar.getPid();
sigar.close();

Incluso aunque no funciona en todas las plataformas, que hace el trabajo en Linux, Windows, OS X y para varias plataformas Unix como aparece aquí.

Este es el código de JConsole, y, potencialmente, jps y VisualVM usos.Utiliza las clases de sun.jvmstat.monitor.* paquete de tool.jar.

package my.code.a003.process;

import sun.jvmstat.monitor.HostIdentifier;
import sun.jvmstat.monitor.MonitorException;
import sun.jvmstat.monitor.MonitoredHost;
import sun.jvmstat.monitor.MonitoredVm;
import sun.jvmstat.monitor.MonitoredVmUtil;
import sun.jvmstat.monitor.VmIdentifier;


public class GetOwnPid {

    public static void main(String[] args) {
        new GetOwnPid().run();
    }

    public void run() {
        System.out.println(getPid(this.getClass()));
    }

    public Integer getPid(Class<?> mainClass) {
        MonitoredHost monitoredHost;
        Set<Integer> activeVmPids;
        try {
            monitoredHost = MonitoredHost.getMonitoredHost(new HostIdentifier((String) null));
            activeVmPids = monitoredHost.activeVms();
            MonitoredVm mvm = null;
            for (Integer vmPid : activeVmPids) {
                try {
                    mvm = monitoredHost.getMonitoredVm(new VmIdentifier(vmPid.toString()));
                    String mvmMainClass = MonitoredVmUtil.mainClass(mvm, true);
                    if (mainClass.getName().equals(mvmMainClass)) {
                        return vmPid;
                    }
                } finally {
                    if (mvm != null) {
                        mvm.detach();
                    }
                }
            }
        } catch (java.net.URISyntaxException e) {
            throw new InternalError(e.getMessage());
        } catch (MonitorException e) {
            throw new InternalError(e.getMessage());
        }
        return null;
    }
}

Hay algunas capturas:

  • El tool.jar es una biblioteca distribuida con Oracle JDK pero no JRE!
  • Usted no puede obtener tool.jar desde Maven repo;configurar con Maven es un poco complicado
  • El tool.jar contiene probablemente dependiente de la plataforma (nativo?) código, así que no es fácil de distribuible
  • Se ejecuta bajo la suposición de que todos (local) que se ejecuta en la JVM apps son "controlables".Parece que a partir de Java 6 todas las aplicaciones en general (a menos que esté activamente a configurar en frente)
  • Probablemente sólo funciona para Java 6+
  • Eclipse no publicar principal de la clase, así que no se Eclipse PID fácilmente Error en MonitoredVmUtil?

ACTUALIZACIÓN:Yo solo se verificó que JPS utiliza de esta manera, que es Jvmstat biblioteca (parte de tool.jar).Así que no hay necesidad de llamar JPS como proceso externo, llamada Jvmstat biblioteca directamente como mi ejemplo se muestra.Usted puede también obtener la lista de todos los Jvm corriendo en localhost de esta manera.Ver JPS código fuente:

Usted puede tratar de getpid() en JNR-Posix.

Tiene un Windows POSIX contenedor que llama getpid() fuera de libc.

Sé que este es un hilo viejo, pero quería llamar a que la API para obtener el PID (así como otros de la manipulación del proceso Java en tiempo de ejecución) se añade a la clase de Proceso en el JDK 9: http://openjdk.java.net/jeps/102

He encontrado una solución que puede ser un poco de un caso extremo y no llegué a probarlo en otro sistema operativo de Windows 10, pero creo que vale la pena destacar.

Si usted se encuentra trabajando con J2V8 y nodejs, puede ejecutar un simple javascript función que devuelve el pid del proceso java.

He aquí un ejemplo:

public static void main(String[] args) {
    NodeJS nodeJS = NodeJS.createNodeJS();
    int pid = nodeJS.getRuntime().executeIntegerScript("process.pid;\n");
    System.out.println(pid);
    nodeJS.release();
}

Agregar a otras soluciones.

con Java 10, para obtener process id

final RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
final long pid = runtime.getPid();
out.println("Process ID is '" + pid);

Aquí está mi solución:

public static boolean isPIDInUse(int pid) {

        try {

            String s = null;
            int java_pid;

            RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean();
            java_pid = Integer.parseInt(rt.getName().substring(0, rt.getName().indexOf("@")));

            if (java_pid == pid) {
                System.out.println("In Use\n");
                return true;
            }
        } catch (Exception e) {
            System.out.println("Exception:  " + e.getMessage());
        }
        return false;
    }

Esto es lo que usé cuando tenía requisito similar.Esto determina el PID del proceso Java correctamente.Deje que el código java para generar un server en un pre-define el número de puerto y, a continuación, ejecutar OS comandos para averiguar el PID que escucha en el puerto.Para Linux

netstat -tupln | grep portNumber
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top