ServerSocket zur Vermeidung von doppelten Programminstanzen

vfl_freak

Premium-User
Moin,

ich habe eine Frage im Zusammenhang mit ServerSockets!

In dem Projekt, das ich hier übernommen habe, wird ein globaler ServerSocket verwendet, um die mehrfache Ausführung des Programms zu verhindern !
Java:
// systemweite globale Deklarationen
// ---------------------------------
// Mutexserverport zur Instanzenkontrolle des Workers
public static final int nMutexServerport = 62987;
protected listenerSocket = null;

.....

private void checkMultiWorkers() 
{
    try 
    {
        listenerSocket = new ServerSocket( nMutexServerport );
    }
    catch( java.net.BindException nbe ) 
    {
        JOptionPane.showMessageDialog( this,
                    "Es ist bereits ein Worker auf diesem System aktiv.\n" +
                    "Sollte dies nicht der Fall sein, bitte den Rechner neu starten!",
                    "Fehler", JOptionPane.ERROR_MESSAGE, null );
       System.exit( -2 );
    }
    catch( final IOException ioe ) 
    {
        JOptionPane.showMessageDialog( this,
                    "Es ist bereits ein Worker auf diesem System aktiv.\n" +
                    "Sollte dies nicht der Fall sein, bitte den Rechner neu starten!",
                    "Fehler", JOptionPane.ERROR_MESSAGE, null );
       System.exit( -2 );
    }
} // checkMultiWorkers()

Wenn ich es richtig verstehe, müsste also hier beim Aufruf einer zweiten Instanz die "BindException" geworfen werden und nach der Meldung der Abbruch erfolgen.

Dieses funktioniert auf vielen PCs in der Firma auch einwandfrei, nur auf einigen leider nicht (geschätzt ca. 20 - 30%).
Mein Vorgänger, der diese Sache mal vor Urzeiten programmiert hat, meinte "es sei nur eine Krücke für Java 1.4.2 gewesen" und würde jetzt mit höheren Versionen nicht mehr funktionieren.

Dies sehe ich allerdings etwas anders, da bei uns inzwischen alle Rechner mind. Java 1.5.x, meist sogar auf V1.6.x laufen!

Hat jemand hiermit Erfahrung resp. weiß, was falsch läuft
Oder gibt es eine andere, Möglichkeit, den Start einer zweiten Instanz zu unterbinden

Danke im voraus für Eure Ideen und Antworten !
Gruß aus OS
Klaus
 
Zuletzt bearbeitet:
Hi,

von meiner Unixerfahrng her würde ich eher mit Lockfiles arbeiten, in denen die PID der aktuellen Instanz vermerkt wird.

Dies funkioniert vereinfacht gesagt so:
Beim Start des Programms wird geschaut, ob die Lockfile existiert.
Unter Unix befindet sich diese normalerweise unterhalb von /tmp, könnte aber auch im Programmverzeichnis selbst liegen. Die Datei hat normalerweise einen Namen wie <PROGRAMMNAME>.lock oder so ähnlich.

Existiert die Datei, so wird diese geöffnet, die ProzessID ausgelesen und geschaut ob der Prozess noch läuft. Wenn ja, dann wird abgebrochen. Falls das Programm nicht mehr läuft (also unsauber beendet wurde), so wird die Datei gelöscht.

Da nun sicher gestellt ist, dass das Programm nicht läuft, wird jetzt das Lockfile angelegt und die ProzessID des Programms darin hinterlegt. Wird das Programm beendet, so wird auch das Lockfile gelöscht.


Hoffe ich habe das verständlich ausgedrückt und dir das Prinzip anschaulich erläutert.
Meiner Meinung nach wäre das eine saubere und bewährte Lösung, denn die 'einen "Dummy-Server" auf nen Port zu starten und wenns nen Fehler gibt dann läuft das Programm schon'-Methode hört sich eher wie ein Hack an ;)

Gruß
BK
 
Moin BK,

erstmal Danke für deiner Antwort :)

Ok, prinzipiell wäre das eine Möglichkeit ... stellt mir nur die Frage, wie ich vom Java-Client aus die WIN(XP)-ProzessID ermitteln kann ...

Mit C++ ist mir das klar, aber wie mache ich das mit Java?

Gruß
Klaus
 
Hallo BK,

ja, über das JNI ... sowas hatte ich befürchtet :-(
Dann muss ich mich da in den nächsten Tagen wohl mal dransetzen ...

Nochmals Danke für Deine Hilfe/Tipps !!

Gruß
Klaus
 
Hi nochmal,

mir ist gerade was anderes eingefallen.
Du könntest dein Programm alle 10 Sekunden oder so einen Timestamp mit der aktuellen Zeit in das Lockfile schreiben lassen.
Beim Start des Programms wird wie bei der PID vorgegangen, nur dass der Inhalt der Lockfile mit der Systemzeit (System.currentTimeMillis() oder so) verglichen wird.

Das würde dir den Weg über JNI ersparen und wäre wieder plattformunabhängig ;)

Ach ja, Danke für die guten Bewertungen, geschieht leider sehr selten, aber sieht man immer wieder gerne :)

Gruß
BK
 
Zurück