# RMI - meine Stub-Class wird nicht gefunden



## paedubucher (7. Jan 2006)

Ich habe mal mit RMI begonnen. Gestern habe ich das ganze auch tatsächlich mal zum laufen gebracht! Heute läuft meine Applikation aber schon bereits nicht mehr.

Die ganze Anwendung ist etwa so aufgebaut:

Package "client"
-Klasse "Client"
Package "common"
-Interface "Summierer"
Package "server"
-Klasse "Server"

Nun die Implementierungen:

Client:

```
package client;

import java.rmi.Naming;
import java.rmi.RMISecurityManager;

import common.Summierer;

public class Client
{
  public static void main(String[] args)
  {
    System.setSecurityManager(new RMISecurityManager());
    try
    {
      Summierer summierer = (Summierer)Naming.lookup("rmi://homews3:1010/Server");
      int result = summierer.summieren(16, 35);
      System.out.println(result);
    }
    catch(Exception ex)
    {
      System.out.println(ex.getMessage());
    }
  }
}
```

Summierer:

```
package common;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Summierer extends Remote
{
  int summieren(int a, int b) throws RemoteException;
}
```

Server:

```
package server;

import java.rmi.Naming;
import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

import common.Summierer;

public class Server extends UnicastRemoteObject implements Summierer
{
  private static final long serialVersionUID = 1L;
  
  public Server() throws RemoteException
  {
  }
  
  public static void main(String[] args)
  {
    System.setSecurityManager(new RMISecurityManager());
    try
    {
      Server server = new Server();
      Naming.bind("rmi://homews3:1010/Server", server);
    }
    catch(Exception ex)
    {
      System.out.println(ex.getMessage());
    }
  }

  public int summieren(int a, int b) throws RemoteException
  {
    return (a + b);
  }
}
```

"homews3" ist übrigens der Name meines Rechners, ich kann ihn auch unter diesem Namen sauber anpingen.

Ich habe diese Klassen sauber codiert, habe dann ins Projekt-Root Verzeichnis gewechselt und folgendermassen kompiliert:


```
javac common/*.java client/*.java server/*.java
```

Das ganze hat prima funktioniert, die Klassen sind sauber erstellt worden. Also bin ich mit folgendem Schritt weitergefahren:


```
rmic server.Server
```

Nun wurde die Datei "Server_Stub.class" erstellt. Scheint also ebenfalls funktioniert zu haben. Bleibt nur noch das freigeben des Ports:


```
rmiregistry 1010
```

Dies funktioniert auch. So, nun will ich den Server ausführen, indem ich folgendes ausführe:


```
java server.Server
```

Ergebnis:


```
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: server.Server_Stub
```

Das verstehe ich einfach nicht! Die Stub-Klasse liegt ja im server-Package und sollte doch gefunden werden! Ich habe auch einmal ein ganzes jar-Archiv erstellt und mithilfe der manifest-Datei die Klasse server.Server als Main-Class angegeben. Das Ergebnis ist genau das gleiche (im .jar war Client jedoch nicht drinne).

Folgende Konfiguration habe ich:
OS: Ubuntu 5.10 mit Linux Kernel 2.6.12
JDK: 1.5_05 (installiert unter /usr/java/current/)

java.policy habe ich mit dem Eintrag "permission java.security.AllPermission;" ergänzt, denn vorher sind immer berechtigungsspezifische Exceptions geworfen wurden.

Mein CLASSPATH ist leer, das müsste aber nichts ausmachen, oder?

Ich habe den Server schon als superuser und als normaler user mit /jre/bin/java und /bin/java ausgeführt, es passiert immer das gleiche.

Kann mir bitte jemand helfen? Ich bin am durchdrehen (gestern ist das Teil noch gelaufen)!!!

EDIT:
Ich habe das ganzen auch schon auf meiner Windows-Kiste versucht! Da wurden genau die gleichen Exceptions geworfen (identische JDK- und policy- Konfiguration).


----------



## Bleiglanz (8. Jan 2006)

rmic common.Summierer

(du brauchst stub und skeleton für all das, das "übers kabel" geht")


----------



## paedubucher (8. Jan 2006)

Bleiglanz hat gesagt.:
			
		

> rmic common.Summierer
> 
> (du brauchst stub und skeleton für all das, das "übers kabel" geht")




```
/usr/java/current/bin/rmic common.Summierer
error: common.Summierer is an interface; stubs are needed only for remote object classes.
```

Das Interface geht ja gar nicht übers Kabel (bzw. bei mir über WLAN), ich stelle das Interface ja dem Client auch zur Verfügung!


----------



## Bleiglanz (8. Jan 2006)

ah stimmt, war Quatsch

liegt die Datei Server_Stub.class im Ordner "server"?


----------



## paedubucher (8. Jan 2006)

Bleiglanz hat gesagt.:
			
		

> ah stimmt, war Quatsch
> 
> liegt die Datei Server_Stub.class im Ordner "server"?



In der Tat. Ich habe jetzt wenigstens mal den Server zum laufen gebracht:



> java -Djava.rmi.server.codebase=file:///home/paedubucher/programming/eclipse/Beispielapplikation/ -jar Server.jar



Nun kann ich den Client auch auf dem gleichen System erfolgreich ausführen. Wenn ich den Client jedoch auf einem anderen Rechner ausführen will, dann meldet er wiederum, dass er die Stub-Klasse nicht finden würde... komisch


----------



## Bleiglanz (8. Jan 2006)

gibts doch nicht?

ist der die _Stub.class auch wirklich im jar drinnen??


----------



## paedubucher (8. Jan 2006)

Bleiglanz hat gesagt.:
			
		

> gibts doch nicht?
> 
> ist der die _Stub.class auch wirklich im jar drinnen??



Ja, 100%-ig!

Beim Ausführen des Clients muss man ja wirklich nicht das Verzeichnis für den Server angeben, das wird ja alles per RMI-Registry gehandlet.

So eine Scheisse, auf meinem Linux Rechner läuft das perfekt, nur auf Windows kann ich nichtmal den Server anständig starten. Das Problem: Ich benötige RMI in einer Projektwoche - und dort gibt es halt nur Windows  :x


----------



## Gast (10. Jan 2006)

ist eine weile her, dass ich was mit rmi gemacht habe, aber afair war das so:

beim server muss der classpath so eingestellt sein, dass er die stubs dort finden kann.
beim client musst du entweder die stubs mitliefern, oder die eigenschaft java.rmi*codebase (irgendwas bei * noch) so setzen, dass er dort die stubs findet. (also die server adresse, falls er die uebers netz ziehen soll).


----------



## paedubucher (10. Jan 2006)

Also, den Server hab ich jetzt so zum laufen gebracht:



> java -Djava.rmi.server.codebase=/home/paedubucher/Server.jar -jar /home/paedubucher/Server.jar



Muss ich dem Client nur die Stub mitliefern oder das ganze Server-Zeuchs?


----------



## paedubucher (10. Jan 2006)

paedubucher hat gesagt.:
			
		

> Also, den Server hab ich jetzt so zum laufen gebracht:
> 
> 
> 
> ...



*Nur die Stub-Klasse*  

Vielen Dank, hat funktioniert!!!  :applaus:


----------

