# Mit RMI Server beenden



## bravedreamer (3. Mrz 2005)

Hi Leute

Ich habe lange und leider auch vergeblich eine Lösung für mein Problem gesucht. Ich hoffe Ihr könnt mir dabei helfen.
Das Problem ist folgendes: Ich habe ein wirklich simples RMI-Programm geschrieben. 
Der Server erzeugt sich selbst eine Registry und registriert sich. Weiters hat er nur noch eine einzige Methode um sich zu beenden. Die Terminierung wird mit System.exit(0) erzwungen.
Der Client ist auch ganz simple: Er verbindet sich mit dem Server und versucht die dortige Methode zur Terminierung auszuführen. 

Nun kommt aber der Haken an der ganzen Sache: Wenn die Methode ausgeführt wird erhalte ich folgende Exception:

```
java.rmi.UnmarshalException: Error unmarshaling return header; nested exception
is:     java.io.EOFException
        at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:203)
        at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:133)
        at systest.testRMI.Server_Stub.terminate(Unknown Source)
        at systest.testRMI.TestClient.main(TestClient.java:41)
Caused by: java.io.EOFException
        at java.io.DataInputStream.readByte(DataInputStream.java:333)
        at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:189)
```
Der Server wird aber planmäßig beendet. Nur der Client bekommt diese Exception. Was habe ich vergessen zu machen bzw. was mache ich falsch?

Danke für die Hilfe


----------



## Guest (4. Mrz 2005)

Beende den Server im getrennten Thread.

```
new Thread(new Runnable() {
  public void run() {
    try {
      Thread.sleep(2000);    // z.B. 2 Sekunden warten
      sendShutdownMessage(); // alle Clients, wenn nötig, benachrichtigen
      shutdown();            // Server kicken
    }
    catch(InterruptedException e) {
      ... // Fehlerbehandlung
    }
  }
}).start();
```


----------



## bravedreamer (4. Mrz 2005)

Hä?

Soll ich auf der Server Seite einen eigenen Thread starten, welcher mir den Server beendet? Oder soll ich aus dem Server einen Thread machen?
Andere Frage: In deinem Quellcode hast du die Möglichkeit implementiert, eine shutdown Message zu allen Clients zu schicken. Wie soll das gehen? Das ganze läuft über RMI. D.h. doch, dass der Client zwar den Server kennt, aber nicht umgekehrt. Oder irre ich mich da?

Wie meinst du das also mit dem Thread?

danke für die Hilfe!!!


----------



## Guest (4. Mrz 2005)

Hallo,

z.Z. hast Du sicherlich sowas:

```
public void beenden() {
  ...
  System.exit(0);
}
```
Dadurch kommt ein Return von der Methode nie beim Client an,
da die VM des Servers einfach gekillt wird.
Der Client wartet auf das Ende des Methodenaufrufs bis ein Timeout
kommt und dann meldet es Fehler, da der Server nicht mehr 
erreichbar ist.
Folge, eine hässlichen Fehlermeldung.

Wenn Du einen neuen Thread in der beenden()-Methode startest,
dann wird die Methode korrekt mit Return beendet, so dass der
Client das auch mitkriegt. In dem neuen Thread wird nach 2 Sekunden
der Server beendet.

```
public void beenden() {
  new Thread(new Runnable() { 
    public void run() { 
      try { 
        Thread.sleep(2000); // z.B. 2 Sekunden warten 
        shutdown();         // Server kicken 
      } 
      catch(InterruptedException e) { 
        ... // Fehlerbehandlung 
      } 
    } 
  }).start();
}
```
Das letzte mit der Benachrichtigung der der Clients läßt sich 
z.B. mit RMI-Callback oder einfacher mit JMS lösen.


----------



## bravedreamer (5. Mrz 2005)

Special thanks

Jetzt läufts.


----------

