PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Programm nur einmal starten



eule
14-04-2008, 19:19
Guten Abend

Ich möchte mein Programm nur einmal starten lassen. Wie mach ich das. Ich habe es versucht in dem ich statische Variable pro gestarteten Programm deklariere, aber das funktioniert nicht.
Wäre für Tipps für einen Ansatz recht dankbar.

mfG Eule

Liberty
14-04-2008, 21:43
Moin,

statische Variablen bringen nichts, da die ja nur in einer Instanz eines Programms global sind.

Es wäre eine Möglichkeit, eine Datei im Homeverzeichnis des Users abzulegen und den Programmstart zu blocken, wenn die Datei bereits existiert.

Eine andere Möglichkeit wären SystemProperties, Du könntest in einer Systemvariablen eine Counter ablegen, wieviele Instanzen eines Programms gerade laufen. Da gibt es in der Klasse System (http://java.sun.com/javase/6/docs/api/java/lang/System.html) Methoden die Systemvariablen lesen und schreiben können und die behalten ihre Gültigkeit auch systemweit.

Der Haken bei diesen Möglichkeiten ist allerdings, dass Du sicherstellen musst, dass entweder die Datei wieder gelöscht oder der Counter zurückgesetzt wird. Dabei könnte ein ShutdownHook (http://java.sun.com/javase/6/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread)) hilfreich sein.

So long,
Liberty

P.S.:
Ganz persönlich würde ich die Systemeigenschaften empfehlen, das ist meiner Meinung nach die elegantere Lösung.

eule
14-04-2008, 22:06
Hi Danke für den Hinweis. Das werd ich morgen mal ausprobieren.

Nur mal so als Verständnisfrage: Wenn ich jetzt den Counter als Systemvariable hochzähle und mein Programm bzw Java stürzt ab, dann kann ich das Programm nicht mehr starten ? Auch nicht nach einem Systemneustart?

Liberty
14-04-2008, 22:23
Moin,

wenn nur Dein Programm abstürzt ist das Problem eher gering, denn selbst bei einem fehlerhaften Programmende wird der ShutdownHook noch ausgeführt.
Und das schöne ist, dass bei einem Systemneustart die Systemvariable gelöscht wird, die ist ja in keiner Konfigurationsdatei oder Startscript hinterlegt und wird erst wieder gesetzt, wenn Dein Programm wieder gestartet wird.

Denk aber daran, erst zu prüfen, ob das Programm starten darf und erst danach den ShutdownHook zu setzen, denn sonst wird der Counter auch dann zurückgesetzt, wenn das Programm gar nicht "richtig" gestartet wurde.

Probier aber am besten erstmal selber aus :)

So long,
Liberty

anda_skoa
15-04-2008, 15:36
Methoden die Systemvariablen lesen und schreiben können und die behalten ihre Gültigkeit auch systemweit.


Bist du dir da sicher?

Das waren bisher immer Variablen der Prozessumgebung, oder?

Ciao,
_

Liberty
15-04-2008, 16:30
Das waren bisher immer Variablen der Prozessumgebung, oder?

Sch***, Du hast sogar recht, ich hab's gerade an der Maschine getestet, an der ich sitze (WinXP), da findet tatsächlich nur die Vererbung Elternprozess->Kindprozess statt.

Es tut mir leid, dann scheint diese Möglichkeit nicht zu funktionieren und bei der Dateivariante gibt's dann das Problem, wie wir die Datei auf jeden Fall wieder wegbekommen, auch bei Stromausfall :(

Mir fällt leider dann auch keine elegante Möglichkeit mehr ein, wie man die anderen Methoden so ausbaut, dass das Programm auch nach einem Systemabsturz ohne grosse Handarbeit wieder lauffähig gemacht werden kann. Evtl. einen Kommandozeilenparameter "--forcestart" oder so einbauen, der einen Programmstart erzwingt und einen vernünftigen Status wiederherstellt...

Ich gebe zu, ich bin ratlos... Aber das Problem ist interessant :D

So long,
Liberty

mehlvogel
15-04-2008, 16:40
Viele Programme benutzen die Variante einer Lockdatei (Firefox bspw.). Das Problem mit dem Abstürzen besteht dann tatsächlich, oft reicht es dann diese Lockdatei zu löschen um das Programm wieder starten zu können.

BLUESCREEN3D
15-04-2008, 17:36
Kann man in Java auf die eigene PID und die Prozessliste zugreifen?
Wenn ja, könntest du die PID in die Lockdatei schreiben und später prüfen, ob der Prozess wirklich existiert.

Boron
16-04-2008, 21:30
Alternativ könnte man auch eine TCP-Verbindung auf einem Port öffnen.
Wenn sich die Verbindung erstellen lässt, ist das Programm kein weiteres Mal gestartet.
Es muss halt ein fixer Port sein.

Waxolunist
17-04-2008, 11:27
Korrekter wäre imho ein Filelock.

Z.B:


import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileLock;

public class Filelock {

public static void main(String[] args) {
String tempdir = System.getProperty("java.io.tmpdir");
File tmpFile = new File(tempdir, "filelock.lock");

try {

RandomAccessFile raf = new RandomAccessFile(tmpFile, "rw");
FileLock lock = raf.getChannel().tryLock();
if(lock == null) {
System.exit(1);
}
new Thread().sleep(20000);

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

Die Lockdatei sollte halt dann einen sehr eindeutigen Namen bekommen, damit nicht andere Programme zufällig den gleichen Namen verwenden.

lg, Christian

Liberty
17-04-2008, 15:28
Moin,

@Waxolunist:
kleine Frage am Rande: Wofür brauchst Du die Schlaf-Anweisung "new Thread.sleep(2000)" ?
Mir ist auch nicht ganz klar, warum, Du einen neuen Thread erschaffst, ist sleep nicht static? :confused:

Bitte um Erleuchtung, was die Aktion bringt...

So long,
Liberty

Waxolunist
17-04-2008, 18:28
Der Thread war nur für das Testen. Ich habe das Programm einmal gestartet und danach innert 20sek noch ungefähr 5 Mal. Dabei hat sich das Programm immer mit 1 beendet. Erst nachdem der Thread beendet war, konnte ich es noch einmal starten.

Man hätte auch etwas einlesen können oder sonst irgendwas. Zum Testen aber schien es mir so ganz gut.

eule
22-04-2008, 19:08
Ich habe gar keine Mail mehr bekommen, dass der Thread ja noch weiter geführt wurde.

Wenn ich das jetzt mit einer Lock-Datei implementiere, dann kann ich doch aber nicht ein Startparameter an das alte Programm senden, oder? Z.B wie in Winamp. Wenn Winamp läuft und ich drück auf eine Datei, dann kann ich sie in die Playlist hängen oder einfach allein abspielen.

BLUESCREEN3D
22-04-2008, 20:20
Wenn ich das jetzt mit einer Lock-Datei implementiere, dann kann ich doch aber nicht ein Startparameter an das alte Programm senden, oder? Z.B wie in Winamp. Wenn Winamp läuft und ich drück auf eine Datei, dann kann ich sie in die Playlist hängen oder einfach allein abspielen.
Startparameter werden, wie der Name schon sagt, nur beim Start übergeben.
Aber dein zweiter Prozess könnte per IPC (http://de.wikipedia.org/wiki/Interprozesskommunikation) die Daten an den ersten Prozess senden und sich dann beenden.

Waxolunist
23-04-2008, 09:40
Also da könntest du einen Thread starten, nachdem das Programm gestartet ist, welches auf Events auf einen Port hört.

Das zweite Programm sendet bei der Stelle mit System.exit die Parameter.


Du kannst dir das mal dazu durchlesen: http://bamboo-dht.org/async-tutorial/async-tutorial.pdf

lg, Christian