2010-06-01 10 views

Antwort

15

Nicht mit reinem Java.

Ihre einfachste Alternative ist die Verwendung von Runtime.exec(), um einen kill -9 <pid>-Befehl als externen Prozess auszuführen.

Leider ist es nicht so einfach, die PID zu bekommen. Sie müssen entweder Reflexions-Schwarzmagie verwenden, um auf das Feld private int pid zuzugreifen, oder mit der Ausgabe des Befehls ps herumspielen.

UPDATE - eigentlich gibt es einen anderen Weg. Erstellen Sie ein kleines Dienstprogramm (C-Programm, Shell-Skript, was auch immer), das die reale externe Anwendung ausführt. Codieren Sie das Dienstprogramm so, dass es sich an die PID des untergeordneten Prozesses erinnert, und richtet einen Signalhandler für SIGTERM ein, der den untergeordneten Prozess SIGKILL wird.

+0

Ich kann es so oder in JNI machen, obwohl ich nicht so eifrig bin, es auf diese Art zu tun, woher kennst du das Pid des Prozesses, den du töten willst? – ekeren

+0

Erstmals danke für diese Antworten. Reflexion und JNI/Exec sind meine letzte Zuflucht, ich frage mich, ob jemand einen eleganteren Weg finden kann, dies zu tun. – ekeren

+0

Ich bin auch hart gegenüber einem Wrapper Scharfrichter, eigentlich mein Chef hart :), So verstehe ich, dass es keine direkte Art und Weise zu tun, dass Sie wissen, von. – ekeren

10

Stephen seine Antwort ist richtig. Ich schrieb, was er sagte:

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

Sie können auch die pid auf diese Weise erhalten:

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

auf Linux, ich führe Befehle durch Java (interaktiver Prozess): nslookup -> google, dies hängt den Prozess, und ich kann diesen Prozess nicht beenden. So, jetzt habe ich Ihren Vorschlag verwendet, aber es beendet diesen Prozess nicht, es hängt einfach und ich kann mein Programm nicht beenden. Ich habe sogar versucht, das Pid manuell zu töten, aber ohne Erfolg, was soll ich tun ??? –

+0

@Space Rocker: Ein einfacher Kill sendet ein SIGTERM. Ein "kill -9" sendet eine SIGKILL. Versuchen Sie "kill -9 -1": das sendet SIGKILL an alle Prozesse in der Prozessgruppe, die pid> 1 sind. Wenn das nicht tötet, dann wird nichts passieren. Aber das wird funktionieren. –

+0

Verwenden Sie den zweiten Weg, um die Selbst-PID zu erhalten. VisualVM macht das gleiche. Der frühere Weg ist hässlich, es ist nicht plattformübergreifend und funktioniert möglicherweise nicht in zukünftigen Java-Versionen. – Espinosa

0

Wenn Sie Prozessnamen kennen Sie pkill

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

Seit Java 1.8

verwenden können

können Sie die Methode destroyForcibly() aufrufen, die die destroy() erfüllt hod standardmäßig, aber gemäß den Java-Dokumenten implementieren alle Unterprozesse, die von ProcessBuilder oder Runtime.exec() zurückgegeben werden, diese Methode.

+1

Leider ruft die Implementierung zur Zeit einfach 'destroy()' auf. Siehe hier: https://bugs.openjdk.java.net/browse/JDK-8056139 – Joe