Alternative zu System.exit(0) und Runtime.getRuntime().exit(0);

Bekomme von SonarQube folgende Meldung:

Wenn dies als deprecated angesehen wird, was ist dann die aktuell empfohlene Vorgehensweise?

Als “deprecated” wird die in SonarQube verwendete Regel angesehen. Stattdessen sollst du die Regel squid:S1147 verwenden, die auch auf System.exit(0) prüft.

Wenn das Ziel wirklich die Beendigung der JVM ist, dann ist System.exit(0) schon ok. In welchem Kontext rufst du das denn auf?

Das Programm soll vollständig beendet werden.

Was für ein Programm? Singlethreaded, multithreaded, Swing…?

[QUOTE=Landei]Was für ein Programm? Singlethreaded, multithreaded, Swing…?[/QUOTE]Frage nebenbei… Ist das nicht relativ egal? “System.exit()” ruft doch JVM-Finalizer auf oder nicht?

@Landei
Singlethread mit Swingoberfläche

Wenn man alles richtig gemacht hat (z.B. beim Hauptfenster setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) aufgerufen hat), sollte die Anwendung auch beenden, wenn jemand das Hauptfenster schließt, oder man das mit setVisible(false) programmatisch tut.

@Spacerat : Warum sollte man System.exit() aufrufen, wenn es ganz normal ohne das geht? Für mich ist das immer nur der Vorschlaghammer in auswegloser Situation, aber nicht der normale Weg, ein Programm zu beenden.

"setVisible(false) reicht afaik nicht, erst ein “dispose()” macht das Fenster inkl. Peer usw. ungültig.

Für mich ist das auch immer der Vorschlaghammer in ausweglosen Situationen. Ich rufe dann immer “System.exit(!=0)” auf (also mit Fehlercodes). Diesen Wert kann man z.B. in Scripts oder ähnlichem verwenden um abnormale Programmabbrüche abzufangen.

[QUOTE=Landei]Wenn man alles richtig gemacht hat (z.B. beim Hauptfenster setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) aufgerufen hat), sollte die Anwendung auch beenden, wenn jemand das Hauptfenster schließt, oder man das mit setVisible(false) programmatisch tut.

@Spacerat : Warum sollte man System.exit() aufrufen, wenn es ganz normal ohne das geht? Für mich ist das immer nur der Vorschlaghammer in auswegloser Situation, aber nicht der normale Weg, ein Programm zu beenden.[/QUOTE]

Zum Beispiel wenn man ein CLI implementiert und mit anderen Rückgaben als 0 auf Fehler hinweist, dann braucht man zumindest für den Fehlerfall ein System.exit(1) oder ähnliches. Die SonarQube Warnung dafür hat mich ehrlich gesagt auch ein wenig gestört, da ich das System.exit dementsprechend nur einmal am in der Main aufrief. Aber man kann dafür ja auch einen Ignore Eintrag machen.

ich gehe mal eher von aus das solche analyse-tools einfach ihre grenzen haben und TO es mit einem simplen rule-set-konflikt zu tun hat

es werden halt gewisse rule-sets enthalten sein die auf bestimmte common-muster der jeweiligen “epoche” dieser tools ausgelegt sind (mal von abgesehen das die entwicklung meist sehr viel zeit in anspruch nimmt und daher manches auch schon so in sich nicht mehr ganz stimmig ist) … und es dabei durchaus einfach zu konflikten kommen wird wenn man anders handelt was dann meist gleich als “fehler” angemakt wird obwohl es halt lediglich nicht den (mit unter nicht ganz stimmigen) rule-sets übereinstimmt

bei der CLI-entwicklung ist es durchaus üblich mit return-codes fehler anzuzeigen und so eine weitere auswertung in einem umgebenen script zur steuerung zu implementieren … bei einer in sich abgeschlossenen GUI-anwendung hat das wenig sinn da es normalerweise weder geprüft noch für irgendwas relevant ist

man sollte sich auch nicht immer zu 100% auf solche tools verlassen
ein extrem-fall wäre z.b. eine allerneueste version die z.b. Swing komplett als “fehler” melden würde da es auf FX ausgelegt ist … trotzdem wäre der code nicht falsch sondern aus sicht dieses tools halt einfach “veraltet”

oder um es anders zu sagen : System.exit() hat durchaus seine berechtigung, allerdings nicht in richtung “NOT-AUS” sondern wirklich nur sinnvoll z.b. bei CLI
wenn es sich um eine GUI handelt die man halt “halbwegs sauber abwürgen” will dann sollte man sich darauf konzentrieren alle nicht-deamon-threads auslaufen zu lassen sowie alle GUI-peers mit dispose() “zu vernichten”

dementsprechend bin ich auch mit dem EXIT_ON_CLOSE eher weniger grün
ich nutze in der regel entweder DISPOSE oder DO_NOTHING und nutze dann die entsprechenden listener um meine “aufräumarbeiten” sauber ablaufen zu lassen

Habe den Code so umgebaut das wenn ich in der Swing Komponente dispose() aufrufe der Code bis zum Ende durchläuft, danke für den Tipp.

Ich habe heute einen Grund gefunden, wann man System.exit() aufrufen muss. Die Hotspot VM schaut nach ein paar Signalen, um das unmittelbare Beenden der JVM erkennen zu können. Mit -Xrs kann man das unterbinden. Dadurch werden auch Shutdown Hooks nicht mehr ausgeführt; diese muss man dann manuell mit System.exit() anstoßen.

Sicher ein sehr sehr spezieller Fall.

sorry, aber “hintenrum” hooks auszulösen obwohl man beim start über einen parameter genau das unterdrückt ist für mich ein design-flaw

auch ist es für die system-stabilität wichtig das ein prozess auf eben solche system-steuercommandos reagieren und entsprechend handeln kann
warum sollte man bewusst in kauf nehmen oder es gar vorsätzlich wollen über solche eingriffe (wie auch immer das auf system-level-ebene überhaupt funktioniert … muss ja letzten endes ein kernel-hook sein) die stabilität des gesamt-systems (das hat schließlich auch auswirkungen auf das cpu-timing und dessen kontrolle) zu gefährden ?

wenn du also auch schon shutdown-hooks nutzt um irgendwas noch aufzuräumen wenn die VM von außen beendet wird anstatt eine möglichkeit zu suchen deinen code sauber durchlaufen zu lassen … dann hast du zumindest meiner meinung einen erheblichen fehler im grundkonzept deiner struktur

selbst wenn wir uns ein unix-system ansehen werden hier beim shutdown sauber alle prozesse über entsprechende hooks beendet (auch wenn dann irgendwo kurz vor dem system-halt noch mal ein SIGTERM und anschließend ein SIGKILL durchgeht) und so diesen codes die möglichkeit gegeben auf ein event zu reagieren zu sich korrekt zu beenden
es ist schon vergleichbar mit der VM und einem shutdown-hook

wie gesagt, ist meine meinung, ich erachte es daher so wie du es beschrieben hast als konzept-fehler als “einen sinnvollen grund über System.exit() shutdown-hooks auszulösen obwohl man dies beim start mit einem parameter unterdrückt”