In Linux quando eseguo la funzione destroy su un oggetto java.lang.Process (che è true digitato java.lang.UNIXProcess) invia un Segnale SIGTERM da elaborare, c'è un modo per ucciderlo con SIGKILL?come posso uccidere un processo Linux in java con SIGKILL Process.destroy() fa SIGTERM
risposta
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.
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);
}
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 ??? –
@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à. –
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
Se si conosce il nome del processo è possibile utilizzare pkill
Runtime.getRuntime().exec("pkill firefox").waitFor();
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.
Purtroppo al momento l'implementazione chiama semplicemente 'destroy()'. Vedi qui: https://bugs.openjdk.java.net/browse/JDK-8056139 – Joe
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
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
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