Uccidere un processo utilizzando Java

Mi piacerebbe sapere come “uccidere” un processo che è stato avviato. Sono a conoscenza dell’API di processo, ma non sono sicuro, se posso usarlo per “uccidere” un processo già in esecuzione, come firefox.exe ecc. Se è ansible utilizzare l’API di processo, puoi indicarmi il direzione corretta? In caso contrario, quali sono le altre opzioni disponibili? Grazie.

Se si avvia il processo da con nella propria applicazione Java (ad esempio chiamando Runtime.exec() o ProcessBuilder.start() ), si ha un riferimento Process valido e si può richiamare il metodo destroy() nella class Process per uccidere quel particolare processo.

Ma sappi che se il processo che invochi crea nuovi sottoprocessi, questi potrebbero non essere terminati (vedi http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4770092 ).

D’altra parte, se vuoi eliminare i processi esterni (che non hai generato dalla tua app Java), allora una cosa che puoi fare è chiamare le utility O / S che ti permettono di farlo. Ad esempio, puoi provare un Runtime.exec() sul comando kill sotto Unix / Linux e controllare i valori di ritorno per assicurarti che l’applicazione sia stata uccisa o meno (0 significa successo, -1 significa errore). Ma ciò ovviamente renderà dipendente la tua piattaforma applicativa.

In Windows probabilmente devi usare questo comando

 taskkill /F /IM .exe 

ucciderlo con forza. Così sarà

 Runtime.getRuntime().exec("taskkill /F /IM .exe") 

AFAIU java.lang.Process è il processo creato da java stesso (come Runtime.exec (‘firefox’))

È ansible utilizzare comandi dipendenti dal sistema come

  Runtime rt = Runtime.getRuntime(); if (System.getProperty("os.name").toLowerCase().indexOf("windows") > -1) rt.exec("taskkill " +....); else rt.exec("kill -9 " +....); 

Accidentalmente mi sono imbattuto in un altro modo per fare un kill di forza su Unix (per coloro che usano Weblogic). Questo è più economico ed elegante di eseguire / bin / kill -9 tramite Runtime.exec () .

 import weblogic.nodemanager.util.Platform; import weblogic.nodemanager.util.ProcessControl; ... ProcessControl pctl = Platform.getProcessControl(); pctl.killProcess(pid); 

E se ti sforzi di ottenere il pid, puoi usare reflection su java.lang.UNIXProcess , ad esempio:

 Process proc = Runtime.getRuntime().exec(cmdarray, envp); if (proc instanceof UNIXProcess) { Field f = proc.getClass().getDeclaredField("pid"); f.setAccessible(true); int pid = f.get(proc); } 

Potrebbe essere un difetto dell’interprete java, ma java su HPUX non esegue un kill -9, ma solo un kill -TERM.

Ho fatto un piccolo test testDestroy.java:

 ProcessBuilder pb = new ProcessBuilder(args); Process process = pb.start(); Thread.sleep(1000); process.destroy(); process.waitFor(); 

E l’invocazione:

 $ tusc -f -p -s signal,kill -e /opt/java1.5/bin/java testDestroy sh -c 'trap "echo TERM" TERM; sleep 10' 

muore dopo 10 secondi (non viene ucciso dopo 1 secondo come previsto) e mostra:

 ... [19999] Received signal 15, SIGTERM, in waitpid(), [caught], no siginfo [19998] kill(19999, SIGTERM) ............................................................................. = 0 ... 

Fare lo stesso su Windows sembra uccidere il processo, anche se il segnale è gestito (ma ciò potrebbe essere dovuto a windows che non usano i segnali per distruggere).

In realtà ho trovato il codice sorgente Java – Process.destroy () per il thread relativo a Linux e l’implementazione openjava sembra utilizzare anche -TERM, il che sembra molto sbagliato.

Provalo:

  String command = "killall "; Process p = Runtime.getRuntime().exec(command); p.destroy(); 

se il processo è ancora attivo, aggiungi:

  p.destroyForcibly(); 

Puoi uccidere un (SIGTERM) un processo di Windows avviato da Java chiamando il metodo destroy sull’object Process. Puoi anche uccidere qualsiasi processo figlio (da Java 9).

Il seguente codice avvia un file batch, attende dieci secondi, quindi elimina tutti i processi secondari e infine elimina il processo batch stesso.

 ProcessBuilder pb = new ProcessBuilder("cmd /c my_script.bat")); Process p = pb.start(); p.waitFor(10, TimeUnit.SECONDS); p.descendants().forEach(ph -> { ph.destroy(); }); p.destroy();