ShutdownHook

TomH

Mitglied
Hallo zusammen,

ich möchte gerne, dass wenn mein Programm nicht ordentlich beendet wird, es sich trotzdem am Applikations-Server abmeldet. Realisieren wollte ich es über die Java-Funktionalität Runtime.getRuntime().addShutdownHook(Thread).
Eigentlich sollte es ja kein Problem sein... man registriert einen Thread, der bei Beendigung des Programms (auch bei Abmeldung oder Herunterfahren vom Betriebssystem... so steht's zumindest in der API) gestartet wird.
Ich vertstehe ja, dass man in der Abarbeitung nicht viel Zeit zur Verfügung hat. Das Abmelden am App-Server dauert keine Sekunde, aber trotzdem funktioniert es nur in seltenen Fällen. Der Thread wird zwar gestartet, aber es ist absoluter Zufall wie weit er kommt. Ich habe mal Debug-Ausgaben eingefügt. Oft ist die erste Debugausgabe (erste Zeile in der run()-Methode des Thread) das Einzige was ausgeführt wird, manchmal kommt er auch etwas weiter, selten bis zum Abmelden.
Ich habe das halbe Internet durchsucht nach einer Lösung aber nix gefunden. Viele Beispiele, die ich gefunden hab dauern sicherlich länger in der Abarbeitung und haben anscheinend trotzdem funktioniert. Was mache ich falsch. So wie es jetzt ist, ist es absolut unbrauchbar.

Falls einer von Euch was konstruktives dazu beitragen kann, wäre ich für das ein oder andere Posting dankbar.

Viele Grüße
Tom
 

nrg

Top Contributor
Java:
	public static void main(final String[] args) {
		Runtime.getRuntime().addShutdownHook( new Thread( new Runnable() {
			public void run() {
				try {
					Thread.sleep( 3000 );
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				for ( int i = 0; i <= 100000; i++ ) {
					System.out.println( i );
				}
			}
		}));
	}
funktioniert bei mir ohne Probleme....

dir ist klar, dass das nicht funzt wenn die VM unnormal beendet wird. Also ein "killen" (in der IDE/Stromausfall/Bluescreen o.ä) würde den shutdownhook nicht mehr ausführen
 
Zuletzt bearbeitet:

TomH

Mitglied
Hallo,
erst mal Danke für deine Mühe...

Wenn ich das Programm "normal" beende, also wenn in deinem Beispiel die main() abgearbeiet ist, oder das Programm über System.exit() beendet wird, funktioniert es bei mir auch.

Mir geht es darum, dass sollte das Programm noch laufen, wenn z.B. der PC heruntergefahren wird, der Thread auch ausgeführt werden soll, und das ist ja expliziet so beschrieben in der Doku zur API. Natürlich hat man da nicht mehr ewig Zeit, und ich weiß auch dass es nicht funktioniert, wenn der Java-Prozess über den Task-Manager abgeschossen wird oder ähnliche Holzhammermethoden angewendet werden.

Ich habe dein Beispiel mal verwendet, habe aber das 3 Sekunden warten weggelassen und nur bis 100.000 gezählt und auf dem Std.Err ausgegeben, wobei das in eine Datei umgeleitet wird. Beim Herunterfahren des PCs kommt er bis knapp 9000, was ich schon für sehr viel halte. Danach hat Windows wohl gemeint, so jetzt hab ich lang genug gewartet und ist heruntergefahren. Das bis kanpp 9000 zählen und ausgeben hat wahrscheinlich sogar länger gedauert als das Abmelden am App-Server, aber das funktioniert trotzdem nicht. Vielleicht sind die Newtzwerkverbindungen auch schon gekappt, ich weiß es nicht.

Aber trotzdem viele Dank für die Mühe

Gruß
Thomas
 

FArt

Top Contributor
Der Shutdownhook zieht nur (sinnvoll), wenn die VM von sich aus beendet wird oder der Prozess das entsprechende Endesignal bekommt (z.B. durch STRG-C auf der Konsole). Alle anderen Signale sorgen für ein sofortiges Ende des Prozesses.
 
S

SlaterB

Gast
wie sieht es explizit mit 'System herunterfahren' aus, ist wohl die Frage

The Java virtual machine shuts down in response to two kinds of events:

* The program exits normally, when the last non-daemon thread exits or when the exit (equivalently, System.exit) method is invoked, or

* The virtual machine is terminated in response to a user interrupt, such as typing ^C, or a system-wide event, such as user logoff or system shutdown.
Runtime (Java Platform SE 6)
 

Murray

Top Contributor
Ein paar Absätze weiter steht
When the virtual machine is terminated due to user logoff or system shutdown the underlying operating system <b>may only allow a fixed amount of time</b> in which to shut down and exit. It is therefore inadvisable to attempt any user interaction or to perform a long-running computation in a shutdown hook.

Und das genau ist wohl das Problem - diese Zeitspanne reicht im konkreten Fall offenbar nicht aus.
 

FArt

Top Contributor
Das ist plattformabhängig und das steht auch da, wenn man ein wenig weiter liest:
Shutdown hooks should also finish their work quickly. When a program invokes exit the expectation is that the virtual machine will promptly shut down and exit. When the virtual machine is terminated due to user logoff or system shutdown the underlying operating system may only allow a fixed amount of time in which to shut down and exit. It is therefore inadvisable to attempt any user interaction or to perform a long-running computation in a shutdown hook.
 

agentone

Bekanntes Mitglied
Warum muss sich denn dein Programm unbedingt am "Applikations-Server" abmelden?

Also ich denke, wenn die VM beendet wird oder Rechner runterfährt (oder beides) wird doch sowieso die Socket geschlossen. Und wenn ein Client halt einfach so die socket schließt ist das halt ein quick-logout und es werden die standardwerte verwendet.
Und wenn das Programm normal beendet wird, kommt halt der normale logout zum tragen.

Ich seh da also kein Problem?! :)
 
Zuletzt bearbeitet:

Developer_X

Top Contributor
Ich habe auch ein ähnliches problem, bei mir geht es aber darum, dass ich wenn ich die eingabeaufforderung schließe, das programm das damit gestartet wurde noch ein paar sachen tun soll, was aber leider nicht passiert wenn ich diesen Shutdownhook anklemme, warum=?

Liegt es an der Eingabeaufforderung?
 

faetzminator

Gesperrter Benutzer
Und das genau ist wohl das Problem - diese Zeitspanne reicht im konkreten Fall offenbar nicht aus.

Ich kann das bestätigen. Bei meinen Linuxsystemen werden alle Daemons (arbeite nicht immer mit GUI, wird aber nicht anders sein ;) ) mit [c]kill -15[/c] (normaler exit, "TERM") beendet, nach x ms wird aber auf die übriggebliebenen Programme [c]kill -9[/c] ("KILL") angewendet.
 

nrg

Top Contributor
@developer: naja. wie oben schon gesagt. normal beendet man einen shellbasierende anwendung mit strg+c. einfach so die Console schließen halte ich für ein unnormales terminieren der vm. brauchst du die console überhaupt?
 

Developer_X

Top Contributor
Es geht drum dass einige benutzer meines programmes das einfach so schließen, und die anderen die eingeloggt sind das stören kann, dass er das einfach mit der console beendet. Außerdem ja, ich brauch die konsole, ich habe meine jar dateien nicht mti einem standardöffnungsprogramm verkknüpft.
 

nrg

Top Contributor
Außerdem ja, ich brauch die konsole, ich habe meine jar dateien nicht mti einem standardöffnungsprogramm verkknüpft.

das ist keine begründung. kannst ja dein programm, sofern es einen EDT hat komplett unabhängig von der console starten, auch mit einer bat. Fragen wir anders: ist dein Programm shell- oder GUIbasierend?
 

TomH

Mitglied
Hallo zusammen,

mein Problem ist zwar noch nicht gelöst (es scheint wohl doch daran zu liegen, dass das BS der VM nicht genug Zeit gibt, den ShutdownHook ordentlich abzuarbeiten).

@agentone: wir (GUI-Devs) sind angehalten, uns am Server ordentlich abzumelden. Außerdem wird in der Datenbank vermerkt, wer sich wann angemeldet oder abgemeldet hat, und ob einer angemeldet ist oder nicht.

Trotzdem möcht ich mich kurz bei allen bedanken, die was dazu geschrieben haben. Ich kenn da andere Java-Foren, da wartet man Wochen, bis da mal einer etwas schreibt, wenn überhaupt.

Gruß
Tom
 

Wortraum

Bekanntes Mitglied
@TomH:
Eine Sekunde halte ich aber wirklich nicht für lang. Jedes Betriebssystem sollte Prozessen diese Zeit zugestehen, sich zu beenden – auch Windows. Mich wundert das Verhalten daher. (Ich weiß, das hilft Dir auch nicht weiter.)
 

Ähnliche Java Themen

Neue Themen


Oben