# Doppelten Programmaufruf verhindern



## reibi (8. Jan 2007)

Hallo: habe das Problem dass ich eine Applikation geschrieben habe, welche auf keinen Fall doppelt gestartet werden sollte. 

Ich könnte natürlich ein Flag in einem Property-File schreiben und dies bei einem neuen Start überprufen.
Dort ist wiederum das Problem: Falls ProgrammInstanz-1 manuell gekillt wird kann das flag nicht mehr upGeDatet werden und somit das programm nicht mehr gestartet werden.

Danke für die Hilfe ;-)


----------



## hupfdule (8. Jan 2007)

Über das Thema gabs hier vor kurzem einen Thread. Ich würde ein Lockfile bevorzugen. Dass dieses gelöscht wird, kannst du über Signalhandling sicherstellen (außer bei kill -9). In dem Thread, den ich meine, findet eine Methode über einen offenen Socket jedoch höheren Anklang.


----------



## Lucifer002 (8. Jan 2007)

Für den Fall das die JVM manuell gekillt wird, würde sich Runtime.addShutdownHook anbieten. Oder du erstellst eine leere Datei und setzt auf dem java.io.File das Flag deleteOnExit, dass könnte auch funktionieren. Weitere möglichkeit würde sich über RMI anbieten, in dem du am localhost einen Nameservice (wenn noch keiner vorhanden ist) erzeugst und deine Applikation bindest. Beim Programmstart würdest du dann eine AlreadyBoundException bekommen, wenn die Application schon gestartet ist. Wäre vllt auch bisschen schöner, weil bei einem Programmabsturz nichts hängen bleibt und falls doch könntest du über RMI eine Workaround machen.

Edit: Gibts einen Link zu dem Thread?


----------



## hupfdule (8. Jan 2007)

Lucifer002 hat gesagt.:
			
		

> Für den Fall das die JVM manuell gekillt wird, würde sich Runtime.addShutdownHook anbieten.


Bist du sicher? Ich meine, dass das nur ausgeführt wird, wenn die VM regulär (also System.exit(int)) beendet wird.



> Gibts einen Link zu dem Thread?


Bestimmt. ;-)
Ich find ihn nur leider grad nicht.... Müsst mal die Suchfunktion quälen (und den Link hier noch posten, wenn ihr ihn gefunden habt).

EDIT: Das hier isser: http://www.java-forum.org/de/viewtopic.php?t=36864


----------



## Lucifer002 (8. Jan 2007)

hupfdule hat gesagt.:
			
		

> Bist du sicher? Ich meine, dass das nur ausgeführt wird, wenn die VM regulär (also System.exit(int)) beendet wird.


Ich weiß das es auch ausgeführt wird, wenn z.B. [STRG]+
	
	
	
	





```
in der Konsole gedrückt wird, weiß nicht wie es sich beim beenden des Prozesses verhält.
```


----------



## Illuvatar (8. Jan 2007)

Wenn Lockfile, dann würde ich das auf keinen Fall danach machen, ob die Datei existiert oder nicht, sondern über java.nio.FileChannel einen exklusiven Lock auf die Datei machen.
Beim Programmstart kannst du dann sagen:
a) Datei existiert nicht => einfach starten
b) Datei existiert, aber Lock kann erhalten werden => starten, aber evtl. Meldung, dass das Programm nicht sauber beendet wurde (ich gehe davon aus, dass die Datei in einem ShutdownHook gelöscht wird)
c) Datei existiert, Lock ist vergeben => Fehlermeldung, dass es die Date schon gibt

Aber RMI erscheint mir jetzt erstmal eine sauberere Variante.


----------



## reibi (8. Jan 2007)

Hallo Zusammen:

Das waren ja ganz schön viele Möglichkeiten. Danke erstmal dafür.

Nur keine davon kann ich dabei in Betracht ziehen zu verwenden. Und zwar möchte ich auf eine Lösung ähnlich Tomcat hinaus; und zwar in folgendem Kontext:

Ich möchte nur eine Applikation gestartet haben und die soll sich etwa so sauber starten und stoppen lassen und zwar über Parameter.

c:\java.exe myapp.class start
c:\java.exe myapp.class stop

also Beispiel; also ähnlich dem Tomcat

Zur Erklärung:
Ich kann kein Serversocket, oder RMI verwenden weil das gegen das Sicherheitskonzept verstösst.

Eine Datei kann ich auch nicht locken, weil das PRG unter Linux und Windows laufen soll; und das geht nicht überall.//wäre aber ne geniale Idee gewesen

Alle beispiele die bislang hier im Forum auf das abzielen laufen auf die Serverlösung ab.

Also falls einer darauf noch ne Idee hat?: Bin sehr dankbar ;-)


----------



## Lucifer002 (8. Jan 2007)

ähm... wenn ich den Tomcat ein zweitesmal starten will bekomme ich doch eine BindException :? 
Die erinnert mich schon irgendwie an Socket!? da wäre RMI auch ein mögliche Lösung, und wie gesagt vllt sogar schöner



> 08.01.2007 19:01:32 org.apache.catalina.core.StandardServer await
> SCHWERWIEGEND: StandardServer.await: create[8005]:
> java.net.BindException: Address already in use: JVM_Bind
> at java.net.PlainSocketImpl.socketBind(Native Method)
> ...


----------



## Illuvatar (8. Jan 2007)

Nicht dass ich mich so sehr mit Linux auskennen würde, aber Locks sollten doch afaik überall gehen? V.a. wenn sie von der Java-API bereitgestellt werden gehe ich da eigentlich davon aus...


----------



## hupfdule (9. Jan 2007)

Illuvatar hat gesagt.:
			
		

> Nicht dass ich mich so sehr mit Linux auskennen würde, aber Locks sollten doch afaik überall gehen? V.a. wenn sie von der Java-API bereitgestellt werden gehe ich da eigentlich davon aus...



Es geht definitv überall. Ich vermute, er will darauf hinaus, dass die Speicherorte für Lockdateien unterschiedlich sind. Allerdings lässt sich das durch eine Abfrage der Umgebung entscheiden.


----------



## Lucifer002 (9. Jan 2007)

er kann noch immer ohne Probleme das Workingdirectory oder das Userhome nehmen


----------



## hupfdule (9. Jan 2007)

Lucifer002 hat gesagt.:
			
		

> er kann noch immer ohne Probleme das Workingdirectory


Nein. Das muss nicht unbedingt schreibbar sein. Außerdem ist es unschön, falls das Programm doch mal abstürzt und das Lockfile nicht gelöscht werden kann, dass dieses dann ewig dort liegen bleibt.


> oder das Userhome nehmen


Das geht. Würde auch verhindern, dass überall auf der Platte Lockfiles liegen bleiben, die bei Absturz nicht gelöscht werden konnten. Trotzdem für Lockfiles nicht sehr schick.


----------

