2010-06-01 9 views

Respuesta

15

No se usa Java puro.

La alternativa más simple es utilizar Runtime.exec() para ejecutar un comando kill -9 <pid> como un proceso externo.

Lamentablemente, no es tan fácil hacerse con el PID. Necesitarás usar reflexión black-magic para acceder al campo private int pid, o perder el resultado del comando ps.

ACTUALIZACIÓN - en realidad, hay otra manera. Cree una pequeña utilidad (programa C, script de shell, lo que sea) que ejecutará la aplicación externa real. Codifique la utilidad para que recuerde el PID del proceso hijo y configure un controlador de señal para SIGTERM que SIGKILL procesará al niño.

+0

Puedo hacerlo así o en JNI, aunque no estoy dispuesto a hacerlo de esta manera, ¿cómo sabes el pid del proceso que desea matar? – ekeren

+0

Primero gracias por estas respuestas. reflexión y JNI/exec son mi último recurso, me pregunto si alguien puede encontrar una manera más elegante de hacer esto. – ekeren

+0

También soy duro con respecto a un verdugo envoltorio, en realidad mi jefe es duro al respecto :), así que entiendo que no hay una forma directa de hacer esto que usted sepa. – ekeren

10

Stephen su respuesta es correcta. Escribí lo que dijo:

public static int getUnixPID(Process process) throws Exception 
{ 
    System.out.println(process.getClass().getName()); 
    if (process.getClass().getName().equals("java.lang.UNIXProcess")) 
    { 
     Class cl = process.getClass(); 
     Field field = cl.getDeclaredField("pid"); 
     field.setAccessible(true); 
     Object pidObject = field.get(process); 
     return (Integer) pidObject; 
    } else 
    { 
     throw new IllegalArgumentException("Needs to be a UNIXProcess"); 
    } 
} 

public static int killUnixProcess(Process process) throws Exception 
{ 
    int pid = getUnixPID(process); 
    return Runtime.getRuntime().exec("kill " + pid).waitFor(); 
} 

También puede obtener el pid de esta manera:

public static int getPID() { 
    String tmp = java.lang.management.ManagementFactory.getRuntimeMXBean().getName(); 
    tmp = tmp.split("@")[0]; 
    return Integer.valueOf(tmp); 
} 
+0

en linux, ejecuto comandos a través de java (proceso interactivo): nslookup -> google, esto bloquea el proceso, y no puedo matar este proceso. Así que ahora usé su sugerencia, pero no finaliza este proceso, simplemente se cuelga y no puedo finalizar mi programa. Incluso traté de matar el pid manualmente, pero en vano, ¿qué debo hacer? –

+0

@Space Rocker: un kill simple envía un SIGTERM. Un "kill -9" envía un SIGKILL. Pruebe "kill -9 -1": envía SIGKILL a todos los procesos en el grupo de procesos pid> 1. Si eso no lo mata, nada lo hará. Pero esto funcionará. –

+0

Definitivamente use la segunda forma de obtener auto PID. VisualVM hace lo mismo. La primera forma es fea, no es multiplataforma, y ​​puede que no funcione en futuras versiones de Java. – Espinosa

0

Si conoce el nombre proceso puede utilizar pkill

Runtime.getRuntime().exec("pkill firefox").waitFor(); 
1

Desde Java 1.8

puede llamar al método destroyForcibly(), que llama al destroy() conocido hod por defecto, pero según los documentos de Java, todos los subprocesos devueltos por ProcessBuilder o Runtime.exec() implementan este método.

+1

Desafortunadamente, actualmente la implementación simplemente llama a 'destroy()'. Vea aquí: https://bugs.openjdk.java.net/browse/JDK-8056139 – Joe

Cuestiones relacionadas