2010-06-01 28 views

risposta

15

Non si utilizza Java puro.

L'alternativa più semplice è utilizzare Runtime.exec() per eseguire un comando kill -9 <pid> come processo esterno.

Sfortunatamente, non è così semplice procurarsi il PID. Dovrai o usare la riflessione black-magic per accedere al campo private int pid, o scherzare con l'output del comando ps.

UPDATE - in realtà, c'è un altro modo. Crea una piccola utility (programma C, script di shell, qualunque) che eseguirà la vera applicazione esterna. Codifica l'utilità in modo che memorizzi il PID del processo figlio e configura un gestore di segnali per SIGTERM che eseguirà SIGKILL del processo figlio.

+0

Posso farlo in questo modo o in JNI, anche se non sono desideroso di farlo in questo modo, come fai a conoscere il pid del processo che vuoi uccidere? – ekeren

+0

Innanzitutto grazie per queste risposte. riflessione e JNI/exec sono la mia ultima risorsa, mi chiedo se qualcuno possa trovare un modo più elegante per farlo. – ekeren

+0

Anche io sono un po 'duro per un boia wrapper, in realtà il mio capo è tosto per questo :), quindi capisco che non c'è un modo semplice per farlo, che tu sappia. – ekeren

10

Stephen la sua risposta è corretta. Ho scritto quello che ha detto:

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(); 
} 

È possibile anche ottenere il pid in questo modo:

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

su linux, eseguo comandi tramite java (processo interattivo): nslookup -> google, questo blocca il processo e non posso uccidere questo processo. Così ora ho usato il tuo suggerimento, ma non termina questo processo, semplicemente si blocca e non posso terminare il mio programma. Ho anche provato a uccidere il pid manualmente, ma inutilmente, cosa dovrei fare ??? –

+0

@Space Rocker: una semplice uccisione invia un SIGTERM. Un "kill -9" invia un SIGKILL. Prova "kill -9 -1": invia SIGKILL a tutto il processo nel gruppo di processi che pid> 1. Se non lo uccide, di quanto non lo farà nulla. Ma questo funzionerà. –

+0

Utilizzare in modo definitivo il secondo modo per ottenere il PID automatico. VisualVM fa lo stesso. Il primo modo è brutto trucco, non è multipiattaforma e potrebbe non funzionare in future versioni di Java. – Espinosa

0

Se si conosce il nome del processo è possibile utilizzare pkill

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

Da Java 1.8

è possibile chiamare il metodo destroyForcibly(), che chiama il destroy() incontrato hod per impostazione predefinita, ma in base ai documenti Java, tutti i sottoprocessi restituiti da ProcessBuilder o Runtime.exec() implementano questo metodo.

+1

Purtroppo al momento l'implementazione chiama semplicemente 'destroy()'. Vedi qui: https://bugs.openjdk.java.net/browse/JDK-8056139 – Joe