Wie kann ich eine Java AWT-Anwendung neu starten? Ich habe eine Schaltfläche, an die ich einen Ereignishandler angehängt habe. Welchen Code soll ich verwenden, um die Anwendung neu zu starten?
Ich möchte das Gleiche tun Application.Restart()
wie in einer C # -Anwendung.
java
restart
application-restart
Azfar Niaz
quelle
quelle
Antworten:
Natürlich ist es möglich, eine Java-Anwendung neu zu starten.
Die folgende Methode zeigt eine Möglichkeit zum Neustarten einer Java-Anwendung:
Grundsätzlich macht es folgendes:
MyClassInTheJar
Klasse verwenden, um den Speicherort des Glases selbst zu finden).quelle
System.exit(0)
der untergeordnete Prozess beendet wird, hat dieselbe Antwort wie ob diese Antwort wirklich funktioniert und warum. Wenn Sie Ihrer Antwort keine vernünftige Erklärung geben können, haben Sie schlechte Arbeit geleistet. Eine Antwort, die mehr Fragen liefert als beantwortet, ist kein Beispiel für eine gründliche Antwort. Gute Antworten zeigen nicht nur den Code, sondern erklären auch, wie und warum sie funktionieren, welche Nachteile sie haben und welche Alternativen es gibt. Sie haben nicht einmal versucht, diese Dinge zu behandeln.Allen gewidmet, die sagen, dass es unmöglich ist.
Dieses Programm sammelt alle verfügbaren Informationen, um die ursprüngliche Befehlszeile wiederherzustellen. Anschließend wird es gestartet, und da es sich um denselben Befehl handelt, wird Ihre Anwendung ein zweites Mal gestartet. Dann beenden wir das ursprüngliche Programm, das untergeordnete Programm läuft weiter (auch unter Linux) und macht genau das Gleiche.
WARNUNG : Wenn Sie dies ausführen, beachten Sie, dass dadurch niemals neue Prozesse erstellt werden, ähnlich wie bei einer Gabelbombe .
quelle
ManagementFactory.getRuntimeMXBean().getInputArguments()
nur die an die JVM übergebenen Eingabeargumente. Es fehlen Parameter, die an Ihre Anwendung übergeben wurden. zB ,java -jar start.jar -MISSED_PARAM=true
. Auf einem Oracle JVM können Sie diese Parameter mit abrufenSystem.getProperty("sun.java.command")
.ProcessBuilder
undinheritIO()
kann die untergeordnete VM so gestartet werden, dass die übergeordnete VM endet.Grundsätzlich kann man nicht. Zumindest nicht zuverlässig. Sie sollten jedoch nicht müssen.
Das kann sich nicht trennen
Um ein Java-Programm neu zu starten, müssen Sie die JVM neu starten. Um die JVM neu zu starten, müssen Sie
Suchen Sie den verwendeten
java
Launcher. Sie können es versuchen,System.getProperty("java.home")
aber es gibt keine Garantie dafür, dass dies tatsächlich auf den Launcher verweist, mit dem Ihre Anwendung gestartet wurde. (Der zurückgegebene Wert verweist möglicherweise nicht auf die JRE, die zum Starten der Anwendung verwendet wurde, oder wurde möglicherweise von überschrieben-Djava.home
.)Sie würden vermutlich wollen die ursprünglichen Speichereinstellungen usw. (ehren
-Xmx
,-Xms
...) , so dass Sie Abbildung benötigen Sie heraus , welche Einstellungen verwendet , bei denen die ersten JVM zu starten. Sie könnten es versuchen,ManagementFactory.getRuntimeMXBean().getInputArguments()
aber es gibt keine Garantie dafür, dass dies die verwendeten Einstellungen widerspiegelt. Dies wird sogar in der Dokumentation dieser Methode beschrieben:Wenn Ihr Programm Eingaben vom
Standard.in
ursprünglichen Standard liest, gehen diese beim Neustart verloren.Viele dieser Tricks und Hacks werden in Gegenwart von a fehlschlagen
SecurityManager
.Das sollte kein Teil brauchen
Ich empfehle Ihnen, Ihre Anwendung so zu gestalten, dass es einfach ist, alles zu bereinigen und anschließend eine neue Instanz Ihrer "Haupt" -Klasse zu erstellen.
Viele Anwendungen sind so konzipiert, dass sie nur eine Instanz in der Hauptmethode erstellen:
Mit diesem Muster sollte es einfach genug sein, Folgendes zu tun:
und lassen Sie
launch()
true nur dann zurück, wenn die Anwendung so heruntergefahren wurde, dass sie neu gestartet werden muss.quelle
java
! Sie vergessen, dass Java eine Sprachspezifikation ist, kein Programm. Was ist, wenn ich Ihr Programm mit einem anderen JVM wie z. B. kaffe ausführe ? Meine Antwort wurde trotzdem aktualisiert :-)Genau genommen kann sich ein Java-Programm nicht selbst neu starten, da es dazu die JVM, in der es ausgeführt wird, beenden und dann erneut starten muss. Sobald die JVM jedoch nicht mehr ausgeführt (beendet) wird, kann keine Aktion ausgeführt werden.
Sie können mit benutzerdefinierten Klassenladeprogrammen einige Tricks ausführen, um die AWT-Komponenten zu laden, zu packen und erneut zu starten. Dies verursacht jedoch wahrscheinlich viele Kopfschmerzen in Bezug auf die GUI-Ereignisschleife.
Abhängig davon, wie die Anwendung gestartet wird, können Sie die JVM in einem Wrapper-Skript starten, das eine do / while-Schleife enthält, die fortgesetzt wird, während die JVM mit einem bestimmten Code beendet wird. Dann müsste die AWT-App aufrufen
System.exit(RESTART_CODE)
. Zum Beispiel beim Skripting von Pseudocode:Die AWT-App sollte die JVM mit etwas anderem als RESTART_CODE bei "normaler" Beendigung beenden, für die kein Neustart erforderlich ist.
quelle
JavaApplicationStub
Version ausgeführt werden. Ich bin mir nicht sicher, ob es einen einfachen Weg gibt, dies zu umgehen.Eclipse wird normalerweise neu gestartet, nachdem ein Plugin installiert wurde. Sie tun dies mit einem Wrapper eclipse.exe (Launcher-App) für Windows. Diese Anwendung führt das Kern-Eclipse-Runner-JAR aus. Wenn die Eclipse-Java-Anwendung mit einem Relaunch-Code beendet wird, startet eclipse.exe die Workbench neu. Sie können ein ähnliches Stück nativen Codes, ein Shell-Skript oder einen anderen Java-Code-Wrapper erstellen, um den Neustart zu erreichen.
quelle
Windows
/ min , um das Skript im minimierten Fenster zu starten
^ & Beenden, um das cmd-Fenster nach Abschluss zu schließen
Ein Beispiel-Cmd-Skript könnte sein
Schlaf 10 Schlaf für 10 Sekunden
quelle
Wenn Sie Ihre App wirklich neu starten müssen, können Sie beim Starten eine separate App schreiben ...
Diese Seite enthält viele verschiedene Beispiele für verschiedene Szenarien:
http://www.rgagnon.com/javadetails/java-0014.html
quelle
Obwohl diese Frage alt und beantwortet ist, bin ich auf ein Problem mit einigen der Lösungen gestoßen und habe beschlossen, meinen Vorschlag in die Mischung aufzunehmen.
Das Problem bei einigen Lösungen besteht darin, dass sie eine einzelne Befehlszeichenfolge erstellen. Dies führt zu Problemen, wenn einige Parameter Leerzeichen enthalten, insbesondere java.home .
Zum Beispiel unter Windows die Linie
Könnte so etwas zurückgeben:
C:\Program Files\Java\jre7\bin\java
Diese Zeichenfolge muss in Anführungszeichen gesetzt oder aufgrund des Leerzeichens in maskiert werden
Program Files
. Kein großes Problem, aber etwas nervig und fehleranfällig, insbesondere bei plattformübergreifenden Anwendungen.Daher erstellt meine Lösung den Befehl als Array von Befehlen:
quelle
Ich habe das Thema selbst recherchiert, als ich auf diese Frage stieß.
Ungeachtet der Tatsache, dass die Antwort bereits akzeptiert wird, möchte ich der Vollständigkeit halber noch einen alternativen Ansatz anbieten. Insbesondere Apache Ant diente als sehr flexible Lösung.
Grundsätzlich läuft alles auf eine Ant-Skriptdatei mit einer einzigen Java-Ausführungsaufgabe hinaus (siehe hier) und hier ) hinaus, die von einem Java-Code aus aufgerufen wird (siehe hier ). Dieser Java - Code, der eine Methode sein kann , Start , könnte ein Teil der Anwendung sein , die neu gestartet werden muss. Die Anwendung muss von der Apache Ant-Bibliothek (jar) abhängig sein.
Wann immer die Anwendung neu gestartet werden muss, sollte sie method aufrufen Einführung und die VM beenden. Für die Ant-Java-Aufgabe sollten die Optionen Fork und Spawn auf true gesetzt sein.
Hier ist ein Beispiel für ein Ant-Skript:
Der Code für die Startmethode sieht möglicherweise folgendermaßen aus:
}}
Sehr praktisch ist, dass das gleiche Skript sowohl für den ersten Start der Anwendung als auch für Neustarts verwendet wird.
quelle
Fügen Sie einfach Informationen hinzu, die in anderen Antworten nicht vorhanden sind.
Wenn procfs
/proc/self/cmdline
verfügbar istWenn Sie in einer Umgebung ausgeführt werden, die procfs bereitstellt und daher über das
/proc
Dateisystem verfügt (was bedeutet, dass dies keine tragbare Lösung ist), können Sie Java lesen lassen/proc/self/cmdline
, um sich selbst neu zu starten.Auf
/proc/self/cmdline
verfügbaren Systemen ist dies wahrscheinlich die eleganteste Methode, um den aktuellen Java-Prozess von Java aus neu zu starten. Kein JNI beteiligt und kein Erraten von Pfaden und Sachen erforderlich. Dadurch werden auch alle an diejava
Binärdatei übergebenen JVM-Optionen berücksichtigt . Die Befehlszeile ist genau identisch mit der des aktuellen JVM-Prozesses.Viele UNIX-Systeme, einschließlich GNU / Linux (einschließlich Android), haben heutzutage procfs. Bei einigen wie FreeBSD ist es jedoch veraltet und wird auslaufen. Mac OS X ist eine Ausnahme in dem Sinne, dass es keine Prozesse gibt . Windows hat auch keine procfs . Cygwin hat Prozesse jedoch für Java nicht sichtbar, da es nur für Anwendungen sichtbar ist, die Cygwin-DLLs anstelle von Windows-Systemaufrufen verwenden, und Java Cygwin nicht kennt.
Vergiss nicht zu benutzen
ProcessBuilder.inheritIO()
Die Standardeinstellung ist, dass
stdin
/stdout
/stderr
(in Java mit dem NamenSystem.in
/System.out
/System.err
) des gestarteten Prozesses auf Pipes gesetzt sind, die es dem aktuell ausgeführten Prozess ermöglichen, mit dem neu gestarteten Prozess zu kommunizieren. Wenn Sie den aktuellen Prozess neu starten möchten, ist dies höchstwahrscheinlich nicht das, was Sie möchten . Stattdessen möchten Sie, dassstdin
//stdout
/stderr
dieselben wie die der aktuellen VM sind. Dies wird als geerbt bezeichnet . Sie können dies tun, indem SieinheritIO()
Ihren Anruf tätigenProcessBuilder
Instanz .Fallstricke unter Windows
Ein häufiger Anwendungsfall einer
restart()
Funktion ist das Neustarten der Anwendung nach einem Update. Das letzte Mal, als ich dies unter Windows versuchte, war dies problematisch. Beim Überschreiben der Anwendungsdatei.jar
mit der neuen Version begann sich die Anwendung schlecht zu verhalten und gab Ausnahmen über die.jar
Datei aus. Ich sage nur, falls dies Ihr Anwendungsfall ist. Damals löste ich das Problem, indem ich die Anwendung in eine Batch-Datei einwickelte und einen magischen Rückgabewert verwendeteSystem.exit()
, den ich in der Batch-Datei abgefragt hatte, und stattdessen die Batch-Datei die Anwendung neu starten ließ.quelle
Alte Frage und all das. Dies ist jedoch ein weiterer Weg, der einige Vorteile bietet.
Unter Windows können Sie den Taskplaner bitten, Ihre App erneut für Sie zu starten. Dies hat den Vorteil, dass Sie eine bestimmte Zeit warten müssen, bevor die App neu gestartet wird. Sie können zum Task-Manager gehen und die Task löschen. Die Wiederholung wird beendet.
quelle
Ähnlich wie Yodas ' verbesserte ' Antwort, jedoch mit weiteren Verbesserungen (sowohl Funktionalität, Lesbarkeit als auch Testbarkeit). Die Ausführung ist jetzt sicher und wird so oft neu gestartet, wie die Anzahl der angegebenen Programmargumente.
JAVA_TOOL_OPTIONS
Optionen.V1.1 Bugfix: Nullzeiger, wenn JAVA_TOOL_OPTIONS nicht gesetzt ist
Beispiel:
quelle
Ich denke, Sie möchten die Anwendung nicht wirklich stoppen, sondern neu starten. Dazu können Sie dies verwenden und Ihren "Reset" vor dem Ruhezustand und nach dem unsichtbaren Fenster hinzufügen.
quelle