Event Handling Neustart

?

_________

Gast
Hallo zusammen,

folgendes Problem: Ich habe eine Anwendung, die im Wesentlichen ein einziges Fenster darstellt. Der Benutzer wird das Fenster häufig schließen und wieder öffnen. Das Öffnen soll 1. durch einen Hotkey und 2. durch das Starten der eigentlichen Anwendung geschehen. Das komplette Neustarten der Anwendung kommt nicht in Frage, da das zu aufwendig für jedes erneute Fensteröffnen wäre. Es soll also nur das Fenster neu geöffnet werden.

Ich kenne einige Verfahren, um Teile der Aufgabe zu lösen:
1) Für die Hotkey-Einbringung kann ich per JNI/A einen Hook einbringen oder, vielleicht sinnvoller, per AHK einfach das Programm starten, was ja auch einer der Apekte ist, das Fenster anzuzeigen.
2) Ich kann per Socket Daten an das Hauptprogramm schicken, wenn es ein weiteres Mal gestartet wird. Dabei benötigt man jedoch ein Socket (ach), was die Firewall verbieten könnte.

Ich hoffe, jemand versteht mein Problem. Was ich brauche, sind noch effiziente Methoden für den 2ten Punkt. Wie kann das Programm am besten im Hintergrund (möglichst ohne größere Auslastung) laufen, um auf erneutes Starten zu reagieren?

LG
 
Zuletzt bearbeitet von einem Moderator:
T

tuxedo

Gast
Etwas Fehleranfälliger als eine Socketverbindung wäre eine temporäre File als Indikator dass die Anwendung schon läuft, oder eben JMX.

Mit JConsole kannst du dir die laufenden Java-Prozesse anschauen. Da das ganze auf JMX basiert, sollte man das auch in einer eigenen Anwendung schaffen. Und da man mit JMX auch Methoden aufrufen kann, könntest du damit auch das Fenster öffnen. Aber wenn ich mich recht erinnere war das mit JMX nicht ganz so easy. Irgend einen Haken gabs da noch. MIr fällt aber nicht mehr ein welcher *grübel* Hatten wir das JMX Thema nicht schon mal hie rim Forum?!

- Alex

[EDIT]Hab den Haken wieder gefunden: Man benötigt die tools.jar aus dem JDK: JMX JConsole-like Connection Dialog - Cordinc Blog[/EDIT]
 
Zuletzt bearbeitet von einem Moderator:
?

_________

Gast
Vielen Dank für die schnelle Antwort!

Etwas Fehleranfälliger als eine Socketverbindung wäre eine temporäre File als Indikator dass die Anwendung schon läuft, oder eben JMX.

Mit JConsole kannst du dir die laufenden Java-Prozesse anschauen. Da das ganze auf JMX basiert, sollte man das auch in einer eigenen Anwendung schaffen. Und da man mit JMX auch Methoden aufrufen kann, könntest du damit auch das Fenster öffnen.

Das sieht... nicht ganz simpel aus.
 
T

tuxedo

Gast
Du könntest auch schauen mit welchen Methoden du keinen Firewall-Dialog bekommst:

* TCP über localhost?
* UDP Multicast über localhost?

Die JMX Lösung, finde ich, abgesehen vom Fakt dass man die tools.jar braucht (wenns nicht über eine RMI Schnittstelle gehen soll, sondern über ein JVM internes native Interface), die beste Lösung. Zudem scheint es zwischen den einzelnen JVM Versionen zum Teil heftige Unterschiede in der tools.jar zu geben...

Auch interessant:

Der "Yourkit Java Profiler" kann sich an bestehende Java-Prozesse attachen, welche nicht speziell mit einem Profiler-Agent versehen wurden. Ich nehme mal an dass auch da JMX und die tools.jar benutzt wird. Allerdings funktioniert das bisher bei mir sehr zuverlässig. Irgendwie haben das die Yourkit-Entwickler wohl in den Griff bekommen...

[EDIT]Grad nachgeschaut: Die liefern mit dem Profiler tatsächlich eine eigene tools.jar und eine JRE mit: In der aktuellen Profiler Version 11.0.8 ist die JRE in Version 1.7.0_05 von Oracle, sowie die tools.jar aus einem 1.6.0_27 Sun JDK enthalten. [/EDIT]

[EDIT]Java Virtual Machine Tools Interface - Wikipedia, the free encyclopedia[/EDIT]
 
Zuletzt bearbeitet von einem Moderator:
T

tuxedo

Gast
Da mich das Thema jetzt doch interessiert, hab ich mal ein wenig ausprobiert. Das Beispiel von JMX JConsole-like Connection Dialog - Cordinc Blog funktioniert prima, wenn man die tools.jar aus einem JDK mit in den Classpath nimmt.

Das interessante ist:

Das Programm sucht nach einer "Agent" Property namens "com.sun.management.jmxremote.localConnectorAddress". Falls die nicht vorhanden ist, wird kurzerhand nachträglich ein Agent für die Ziel JVM gesetzt. Dieser entstammt der von der Ziel-Anwendung verwendeten JVM und liegt üblicherweise im lib-Ordner der JRE in der JAR "management-agent.jar".

Sprich: Man selbst braucht nur eine funktionierender tools.jar. Damit kann man dann wohl jede beliebige Anwendung nachträglich mit einem Management-Agent versehen, welcher dann die oben genannte Property setzt und über die darin enthaltene "URL" erreichbar ist.

Der Clou: Über die Tools.jar erreicht man die gewünschte JVM via JVM interner Inter-Prozess-Kommunikation (wohl diverse JNI Aufrufe/Callbacks), und macht sie nachträglich über JMX/RMI/Localhost erreichbar.

Eigentlich eine geniale Sache...

Was heisst das nun für die vom TS gewünschte Funktion?!

Nun, da das JVM Tools-Interface auch nichts anderes macht wie die Ziel-VM via JMX über Localhost erreichbar zu machen, kann man das sicherlich in der eigenen Anwendung auch selbst forcieren. Da ich bei der benutzung von JConsole (und jetzt auch mit dem Beispielprogramm) unter Windows keinen DIalog bzgl. "Erlauben in der Windows-Firewall" gesehen habe, gehe ich mal spontan davon aus, dass die Windows-Firewall sich bei Socket-Servern auf Localhost und einem Port >1024 (RMI liegt ja üblicherweise auf 1099) einfach nicht beschwert. Ergo müsste man entweder selbst JMX oder einen anderen eigenen Socket-Dienst auf Localhost und >1024 einsetzen können um das Problem des TS zu lösen.

Aber mit JMX ist das ganze wohl etwas "praktischer", da man auch schnell mal mit JConsole eine Management-Methode aufrufen kann.

[EDIT]Okay, ich muss meine Aussage relativieren:

Wenn man eine jungfräuliche Windows-Firewall hat, dann kommt auch mit JConsole beim attachen auf den Prozess ein Firewall-Dialog. Interessanterweise kann man hier auch auf "abbrechen" drücken und sich dennoch attachen. Und in den Firewalleinstellungen wird eine Erlaubnis für JAVA eingetragen. Zumindest für public und home.

Es ist also egal ob und was man als Anwender da klickt: Man muss nur einmal klicken. Ob zulassen oder nicht scheint egal zu sein.
[/EDIT]

[EDIT]Schon wieder ein update: Hab gegoogelt und eine Lösung gefunden (zumindest für den eigenen SocketServer:

Die Lösung gibt's hier: java - Avoid Windows Firewall popup with Sockets on localhost - Stack Overflow

Java:
        int port = 12345;
        ServerSocket ss = new ServerSocket(port, 1, InetAddress.getByName(null)); // null verwenden um den Firewall-Dialog zu vermeiden

Wenn man das jetzt noch für das nachträgliche Laden des JMX Agents tun könnte: Perfekt. Für die eigene Anwendung die von Haus aus den Dienst braucht: Eigenen Socket, oder ggf. JMX auf geiche Art und Weise die Socket-Adresse mitteilen (falls das geht).
[/EDIT]

[EDIT]Statt null geht auch "127.0.0.1". "localhost" hingegen funktioniert nicht. Könnte an einer schrägen eigenheit der Namensauflösung in Windows liegen?![/EDIT]

[EDIT]AUch lesenswert: Monitoring and Management Using JMX Technology - Java SE Monitoring and Management Guide[/EDIT]
 
Zuletzt bearbeitet von einem Moderator:

Ähnliche Java Themen

Neue Themen


Oben