Domanda

Ho un'applicazione Java che consente di avviare un'altra applicazione java.Il launcher ha un timer di watchdog e riceve notifiche periodiche dal secondo VM.Tuttavia, se non riceve le notifiche, poi con la seconda macchina virtuale deve essere ucciso e il programma di avvio di eseguire qualche altra clean-up delle attività.

La domanda è, c'è un modo per fare questo usando solo java?finora devo utilizzare alcuni metodi nativi per eseguire questa operazione e si è in qualche modo brutto.

Grazie!

È stato utile?

Soluzione

Mi potrebbe mancare qualcosa, ma non si può chiamare il destroy() metodo Process oggetto restituito da Runtime.exec()?

Altri suggerimenti

È possibile utilizzare java.lang.Processo per fare quello che vuoi.Una volta creato il nidificato di processo e di avere un punto di riferimento per l'istanza di Processo, è possibile ottenere i riferimenti per i suoi standard e err flussi.È possibile monitorare periodicamente quelli, e la chiamata .destroy (), se si desidera chiudere il processo.Il tutto potrebbe essere qualcosa di simile a questo:

Process nestedProcess = new ProcessBuilder("java mysubprocess").start();
InputStream nestedStdOut = nestedProcess.getInputStream(); //kinda backwards, I know
InputStream nestedStdErr = nestedProcess.getErrorStream();
while (true) {
    /*
       TODO: read from the std out or std err (or get notifications some other way)
       Then put the real "kill-me" logic here instead of if (false)
    */
    if (false) {
        nestedProcess.destroy();
        //perform post-destruction cleanup here
        return;
    }

    Thread.currentThread().sleep(1000L); //wait for a bit
}

Spero che questo aiuta,

Sean

Si potrebbe anche pubblicare un servizio (via juta, tela di iuta, ecc) il secondo JVM che le chiamate di Sistema.exit() e consumare dal watchdog JVM.Se solo si desidera arrestare il secondo JVM verso il basso quando si interrompe l'invio di tali notifiche periodiche, potrebbe non essere in stato di rispondere alla chiamata di servizio.

La chiamata di comandi di shell con java.lang.Runtime.exec() è probabilmente la vostra scommessa migliore.

Il solito modo di fare questo è quello di chiamare Processo.destroy()...comunque è una soluzione incompleta dal momento che quando si utilizza il sun JVM su *nix distruggere le mappe su un SIGTERM che non è garantito per terminare il processo (per questo è necessario SIGKILL così).Il risultato netto è che non si può fare un vero e proprio processo di gestione utilizzando Java.

Ci sono alcuni bug aperto su questo problema, vedere:testo del link

java.lang.Il processo ha un waitFor() metodo di aspettare per un processo a morire, e destroy() metodo per uccidere il processo secondario.

OK la torsione del gist è come segue:

Stavo usando il Processo di API per chiudere la seconda macchina virtuale, ma non funziona.

Il motivo è che la mia seconda domanda è un Eclipse RCP Applicazione, e ho lanciato utilizzando il eclipse.exe launcher incluso.

Tuttavia, questo significa che il Processo di API destroy() metodo per obiettivo il eclipse.exe processo.L'uccisione di questo processo lascia il Processo Java indenne.Così, uno dei miei colleghi ha scritto una piccola applicazione che permette di uccidere la giusta applicazione.

Perciò una delle soluzioni per utilizzare il Processo di API (e rimuovere ridondante medio di passaggi), è di ottenere via con l'Eclipse launcher, essendo la mia prima macchina virtuale duplicare tutte le sue funzionalità.

Credo che dovrò andare al lavoro.

Si dovrebbe essere in grado di farlo in java.lang.Runtime.exec e comandi di shell.

Si può avere il codice java rilevare la piattaforma in fase di runtime e a fuoco spento la piattaforma di uccidere processo di comando.Questo è davvero un affinamento della tua soluzione attuale.

C'è anche Processo.destroy(), se si sta utilizzando il ProcessBuilder API

Non è esattamente il processo di gestione, ma si potrebbe iniziare un rmi server in java virtual machine che si sta avviando, e associare un remoto esempio con un metodo che si occupa di tutto ciò di pulitura richieste e le chiamate di Sistema.exit().Il primo vm può quindi chiamare il metodo remoto a chiudere il secondo vm.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top