2009-06-22 18 views
19

Sono interessato a diversi approcci per arrestare con garbo un programma da riga di comando Java. L'invio di un segnale di uccisione non è un'opzione.Il modo migliore per arrestare con garbo un programma da riga di comando Java

Posso pensare ad alcuni approcci diversi.

  1. Aprire una porta e attendere una connessione. Quando ne viene fatto uno, con garbo si spegne.
  2. Guarda per creare un file, quindi spegnerlo.
  3. Leggere alcuni input dal terminale, ad esempio "eseguire l'arresto".

Il terzo non è l'ideale, poiché spesso l'uscita del programma viene pompata sullo schermo. Il primo richiede troppo sforzo (sono pigro). La maggior parte dei programmatori usa la seconda opzione? Se no, cos'altro è possibile/elegante/semplice?

+0

Intendi per un processo di uccidere il tuo programma da riga di comando java? – Tom

+2

Perché l'invio del segnale di eliminazione non è un'opzione? Come menzionato nelle risposte di seguito, puoi catturare e gestire il segnale di uccisione con garbo con i ganci di arresto. – toluju

risposta

2

Le prime due opzioni sono semplici da implementare. Potresti anche usare alcune cose di JMX (non ne so molto). Tomcat utilizza il primo approccio e ho applicato 1 e 2 in due dei miei progetti.

9

si potrebbe provare a utilizzare Runtime.getRuntime().addShutdownHook() che dovrebbe soddisfare il vostro requisito. In questo modo è possibile registrare un hook per effettuare le pulizie, al fine di eseguire un arresto regolare.

EDIT

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread) vuoto addShutdownHook (gancio Thread) pubblico Registra un nuovo hook arresto virtuale macchina. La macchina virtuale Java spegne in risposta a due tipi di eventi:

  • Il programma termina normalmente, quando le ultime non daemon thread termina o quando l'uscita (equivalentemente, System.exit) viene richiamato il metodo, o
  • La macchina virtuale viene terminata in risposta a un'interruzione utente, come la digitazione di^C o un evento a livello di sistema, come la disconnessione dell'utente o l'arresto del sistema.
+0

Questo non funziona quando cntrl + c viene eseguito. –

+0

Ma mike, è il modo per degradare con grazia, se si preme ctrl + c, qualsiasi programma cmd verrà terminato con un segnale kill. –

+0

Tuttavia, nessuna delle altre opzioni menzionate avrebbe funzionato, quindi il comportamento su ctrl + c probabilmente non è rilevante per decidere su uno di questi metodi. – Herms

16

si può provare qualcosa di simile:

Runtime.getRuntime().addShutdownHook(new Thread() { 
    public void run() { /* 
     my shutdown code here 
    */ } 
}); 

edit:

il gancio di arresto non eseguirà la chiusura delle app. al contrario, offre allo sviluppatore un modo per eseguire qualsiasi ripulitura che desidera all'arresto.

dal JavaDoc per Runtime (una buona lettura se si prevede di utilizzare questo metodo):

Un gancio di arresto è semplicemente un filo inizializzato ma unstarted. Quando la macchina virtuale inizia la sua sequenza di spegnimento, avvierà tutti i ganci di arresto registrati in un ordine non specificato e li lascerà correre simultaneamente. Al termine di tutti gli hook, eseguirà tutti i finalizzatori non inviati se la finalizzazione all'uscita è stata abilitata. Alla fine, la macchina virtuale si fermerà. ...

+0

Come fa a chiudere il suo programma? –

+0

modificato. Spero che risponda alla tua domanda. – akf

+0

Il metodo run non dovrebbe avere un'annotazione @ Override? –

5

Il vantaggio della seconda opzione, ovvero il controllo di un file, rispetto al primo, l'ascolto su una porta, è che si ha qualche possibilità di sicurezza.

È possibile impostare le autorizzazioni sulla directory in cui è stato creato il file in modo che solo gli utenti appropriati possano chiudere il programma. Se ascolti su una porta qualsiasi utente può connettersi ad esso.

+0

È possibile limitare le chiamate in arrivo in base all'indirizzo IP del client. Ad esempio, consentire le connessioni solo da localhost. Esci solo quando è l'indirizzo IP corretto, altrimenti chiudi la connessione e continua ad ascoltarne una nuova. – akarnokd

+0

@ kd304 - Limitare gli indirizzi IP consente comunque a qualsiasi utente sul sistema locale di arrestare il processo. Impostando le autorizzazioni sulla directory, è possibile consentire solo un controllo utente specifico del processo. –

0

Suggerisco di utilizzare il gancio di arresto. Permetterà al tuo programma di essere controllato usando strumenti OS standard. Inoltre non ha bisogno di alcun accesso aggiuntivo a risorse esterne (disco, porte, qualunque cosa).

2

Se si desidera utilizzare la versione socket, è molto semplice da implementare. Ecco il codice:

ServerSocket server = new ServerSocket(8080); 
System.out.println("Socket listening!"); 
server.accept(); 
System.out.println("Connection received!"); 

si potrebbe facilmente inserire questo codice in un thread separato che si avvia con il vostro programma, e poi ne modifica lo stato globale di avviare l'arresto.

1

Considerare di avere un componente JMX. Quindi puoi collegarti a JConsole localmente o in rete e comunicare con il tuo componente. Quindi il componente può spegnere correttamente il programma.

Con Java 6 u 10 o successivo, è possibile fare lo stesso con JVisualVM.

Problemi correlati