# RMI Server starten - rmiregistry Aufruf?



## Guest (28. Mai 2008)

Hallo,


ich bekomme es einfach nicht hin den Server zu starten.
Laut meinem Buch muss erst folgende Zeile eingegeben werden, woran es bei mir schon hapert:

```
start /Dbuild rmiregistry
```
wird das ganze in der DOS-Kommandozeile eingegeben?
Wenn ja, in welchem Pfad?

Anschließend soll ich den Server starten:

```
start java -cp build EchoServer
```

Ich bekomme es momentan nichtmal hin die rmiregistry zu starten...


----------



## L-ectron-X (28. Mai 2008)

Du kannst auch die Registry schon im Server mitstarten:

```
LocateRegistry.createRegistry(Registry.REGISTRY_PORT); //Port binden
Registry registry = LocateRegistry.getRegistry();
```


----------



## Guest (28. Mai 2008)

^^ok wunderbar server läuft jetzt! 
aber ich schaffe es noch nicht den client mit dem server zu verbinden... wenn ich den client starte erhalte ich folgende meldung:

```
java EchoClient <host> <text>
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)
```

oder muss ich den irgendwie über die DOS Konsole starten?

Serverklasse:

```
package neu;

import java.rmi.*;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class EchoServer {
  public static void main(String args[]) throws Exception {
    
    Remote remote = new EchoImpl();
    LocateRegistry.createRegistry(Registry.REGISTRY_PORT); //Port binden
    Registry registry = LocateRegistry.getRegistry();
    Naming.rebind("echo", remote);
    System.out.println("EchoServer gestartet ...");  
    
  } 
  
}
```

Clientklasse:



```
package neu;



import java.rmi.*;

public class EchoClient {
  public static void main(String args[]) throws Exception {
    if (args.length != 2) {
      System.err.println("java EchoClient <host> <text>");
      System.exit(1);
    }

    String host = args[0];
    String text = args[1];

    Echo remote = (Echo) Naming.lookup("//" + host + "/echo");
    String received = remote.getEcho(text);
    System.out.println(received);
  }
}
```


----------



## Guest (28. Mai 2008)

oder besser gefragt:
Wie kann ich dem Client die Argumente liefer (host), (text)?


----------



## tuxedo (29. Mai 2008)

Wie wär's mit der Kommandozeile?

> java neu.EchoClient meinEchoServerHost meinEchoText

Dir scheint die eine oder andere Grundlage zu fehlen. Schmökere doch ab und zu mal in der "Java Insel". 

- Alex


----------



## L-ectron-X (29. Mai 2008)

Meine RMI-Kenntisse sind etwas eingerostet, hab schon länger nichts mehr damit gemacht. Aber das Folgende funktioniert bei mir.

Das Remote-Interface:

```
import java.rmi.*;

public interface Echo extends Remote {
   public String getEcho(String text) throws RemoteException;
}
```
(wird vom Server und vom Client benötigt)

Die Implementierung der Methode:

```
import java.rmi.*;

public class EchoImpl implements Echo {
   public String getEcho(String text) throws RemoteException {
      return text;
   }
}
```

Der Client:

```
import java.net.*;
import java.rmi.*;
import java.rmi.registry.*;

public class EchoClient {
   public static void main(String args[]) {
      if (args.length != 2) {
         System.err.println("java EchoClient <host> <text>");
         return;
      }

      try {
         Echo echo = (Echo)Naming.lookup("//" + args[0] + "/Echo");
         String received = echo.getEcho(args[1]);
         System.out.println(received);
      }
      catch(MalformedURLException murle) {
         murle.printStackTrace();
      }
      catch(NotBoundException nbe) {
         nbe.printStackTrace();
      }
      catch(RemoteException re) {
         re.printStackTrace();
      }
   }
}
```

Der Server:

```
import java.net.*;
import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.*;

public class EchoServer {
   public static void main(String args[]) {
      try {
         String hostname = InetAddress.getLocalHost().getHostName();
         LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
         System.out.println("EchoServer auf ["+hostname+"] gestartet...");
         
         EchoImpl echo = new EchoImpl();
         Echo stub = (Echo)UnicastRemoteObject.exportObject(echo, 0);
         
         Registry registry = LocateRegistry.getRegistry();
         registry.rebind("Echo", stub );
         System.out.println("Echo-Dienst angemeldet...");
      }
      catch(java.net.UnknownHostException uhe) {
         uhe.printStackTrace();
      }
      catch(RemoteException re) {
         re.printStackTrace();
      }
   }
}
```


----------



## Guest (29. Mai 2008)

^^^danke erstmal!

wenn ich den Server du du gepostet hast starten möchte kommt folgende Meldung...


```
EchoServer auf [boSSti] gestartet...
java.rmi.server.ExportException: object already exported
        at sun.rmi.transport.ObjectTable.putTarget(ObjectTable.java:172)
        at sun.rmi.transport.Transport.exportObject(Transport.java:74)
        at sun.rmi.transport.tcp.TCPTransport.exportObject(TCPTransport.java:229)
        at sun.rmi.transport.tcp.TCPEndpoint.exportObject(TCPEndpoint.java:393)
        at sun.rmi.transport.LiveRef.exportObject(LiveRef.java:129)
        at sun.rmi.server.UnicastServerRef.exportObject(UnicastServerRef.java:190)
        at java.rmi.server.UnicastRemoteObject.exportObject(UnicastRemoteObject.java:293)
        at java.rmi.server.UnicastRemoteObject.exportObject(UnicastRemoteObject.java:235)
        at neu.EchoServer.main(EchoServer.java:16)
```

ich denke mal der server startet, aber die registrierung in der registry funzt irgendwie nicht...


----------



## tuxedo (29. Mai 2008)

Problem ist dass Zeiel 13 und 14 des Server das gleiche machen wie Zeile 17. 
Kommentier mal Zeile 13 und 14 aus und probiers nochmal.

- Alex


----------



## tuxedo (29. Mai 2008)

Problem ist dass Zeiel 13 und 14 des Server das gleiche machen wie Zeile 17. 
Kommentier mal Zeile 13 und 14 aus und probiers nochmal.

- Alex+


[update]

mist, ich erzähl mal wieder blödsinn.

Würde dennoch Zeile 13 und 14 weglassen, und in Zeile 17 folgendes schreiben:

>>  registry.rebind("Echo", echo); 

Bei mir hat dieser Weg in nem Dutzend Anwendungen bestens funktioniert. Allerdings sollte dann EchoImpl von UnicastRemoteObject erben. Hat bei mir immer bestens funktioniert.

- Alex


----------



## Guest (29. Mai 2008)

ja aber dann funktioniert doch die zeile 17 mit dem rebind nicht mehr. da wird doch das stub objekt übergeben...


----------



## Guest (29. Mai 2008)

ok super danke, server läuft jetzt!

aber wenn ich jetzt den client starten möchte im Pfad "C:\Users\b0SSti\Documents\NetBeansProjects\neu\src\neu>" (in der auch die Klasse EchoClient liegt) mit 

java EchoClient boSSti bla

bekomme ich in der Kommandozeile folgende Fehlermeldung:

```
Exception in thread "main" java.lang.NoClassDefFoundError: EchoClient
Caused by: java.lang.ClassNotFoundException: EchoClient
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClassInternal(Unknown Source)
```


----------



## tuxedo (29. Mai 2008)

die brauchst nicht die klasse, sondern das interface. die implementierung des remote-objekts interessiert dich ja nicht.

- Alex


----------



## Guest (29. Mai 2008)

ok!
dann möchte ich jetzt das interface aufrufen, klappt aber auch nicht.
vielen dank für eure geduld!!!


```
C:\Users\b0SSti\Documents\NetBeansProjects\neu\src\neu>java Echo localhost hello

Exception in thread "main" java.lang.NoClassDefFoundError: Echo
Caused by: java.lang.ClassNotFoundException: Echo
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClassInternal(Unknown Source)

C:\Users\b0SSti\Documents\NetBeansProjects\neu\src\neu>java Echo boSSti hello
Exception in thread "main" java.lang.NoClassDefFoundError: Echo
Caused by: java.lang.ClassNotFoundException: Echo
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClassInternal(Unknown Source)

C:\Users\b0SSti\Documents\NetBeansProjects\neu\src\neu>java -cp build Echo boSSt
i hello
Exception in thread "main" java.lang.NoClassDefFoundError: Echo
Caused by: java.lang.ClassNotFoundException: Echo
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClassInternal(Unknown Source)

C:\Users\b0SSti\Documents\NetBeansProjects\neu\src\neu>
```


----------



## tuxedo (29. Mai 2008)

Wer hat was von "interface aufrufen" gesagt?

Das Interface "Echo" muss beim Client im Classpath verfügbar sein. "EchoImpl" interessiert den Client nicht. 

Und "NoClassDefFoundError: Echo " heisst eben schlicht und ergreifend, dass "Echo" nicht im Classpath des Clients ist. Du musst dieses Interface eben nicht nur dem Server zugänglich machen, sondern auch dem Client. Dann funktionierts auch.

- Alex


----------



## Guest (29. Mai 2008)

danke, wie mache ich es dem client zugänglich?


----------



## tuxedo (29. Mai 2008)

Sagt dir denn "Classpath" irgendwas? Wenn nicht, dann solltest du ganz dringend das hier lesen:

http://www.galileocomputing.de/open...27_003.htm#mj573486ebb156161e7f61bb7e793c4d61
--> 27.3 Der Java-Interpreter java: Option "-cp classpath"

http://www.galileocomputing.de/open...09_003.htm#mj16c95461a1b7b6e3d7bde6f9557d056e
--> 9.3.2 Setzen des Klassenpfades


----------



## Guest (31. Mai 2008)

kann mir einer vielleicht bitte noch die frage beantworten?
dann bin ich auch durch!
danke!


----------



## L-ectron-X (31. Mai 2008)

Kopiere das Interface in den Sichtbarkeitsbereich des Clients. Also einfach zu den Klassen des Clients dazu legen.


----------

