# RMI - Probleme beim Starten des Clients



## TheNose (9. Apr 2007)

Hallo!

Ich arbeite mich zur Zeit in RMI ein. Habe ein Beispielprogramm geschrieben. Der Server startet ohne Probleme, allerdings fliegt der Client immer mit einer Exception weg. Aber jetzt erstmal der Reihe nach:

Mein Interface sieht so aus:

```
package de.hft_stuttgart.verteiltesysteme.ostereier.server;

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

public interface RemoteInterface extends Remote { 

	public int suchen(int id, int feldnummer) throws RemoteException;
	
	public int getLength() throws RemoteException;
```
	public int getId() throws RemoteException;

}

Meine Serverklasse so:

```
package de.hft_stuttgart.verteiltesysteme.ostereier.server;


import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.Vector;


public class Server extends UnicastRemoteObject implements RemoteInterface {


	private static final long serialVersionUID = -2679964088057799575L;
	
	private Vector<Integer> feld;
	private Vector<Integer> clients;
	
	
	public Server() throws RemoteException {
		super();
	}
	
	public static void main(String args[]) {
		if (System.getSecurityManager() == null) {
		    System.setSecurityManager(new SecurityManager());
		}
		
		try { 
			   LocateRegistry.createRegistry( Registry.REGISTRY_PORT    );
			  
			  
			  
			} 
			catch ( RemoteException e )  {  }
		
		System.out.println("sadsad");
		try {
			Server serv = new Server();
			Naming.rebind("//localhost:1099/Server", serv);
		
		}
		catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public int getLength() throws RemoteException {
		return feld.size();
	}

	public int suchen(int id, int feldnummer) throws RemoteException {
		try {
			this.wait(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if (feld.get(feldnummer) == 1) {
			clients.set(id, clients.get(id) + 1);
			return 1;
		}
		else {
			return 0;
		}
		
	}

	public int getId() throws RemoteException {
		clients.add(clients.size() +1);
		return clients.size();
	}	

}
```

Und meine Client-Klasse so:

```
package de.hft_stuttgart.verteiltesysteme.ostereier.client;

/**
 * 
 */


import java.rmi.Naming;

/**
 * @author andreas
 *
 */
public class Client {
	
	public static void main(String[] args) {
		if (System.getSecurityManager() == null) {
		    System.setSecurityManager(new SecurityManager());
		}
		
		try {
			RemoteInterface suchen = (RemoteInterface) Naming.lookup("Server");
			System.out.println("Client-Id: " + suchen.getId());
			System.out.println("Feldgröße: " + suchen.getLength());
			
		} catch ( Exception e) {
			e.printStackTrace();
		}
	}

}
```

Ich arbeite unter Linux. Den Server starte ich wie folgt:

```
java -cp /home/andreas/Desktop/server.jar -Djava.security.policy=/home/andreas/Desktop/policy.all de.hft_stuttgart.verteiltesysteme.ostereier.server.Server
```

Funktioniert einwandfrei. Auch rmiregistery wird mitgestartet.

Dann rufe ich den Client wie folgt auf:

```
java -cp /home/andreas/Desktop/client.jar -Djava.security.policy=/home/andreas/Desktop/policy.all de.hft_stuttgart.verteiltesysteme.ostereier.client.Client
```

Jetzt bekomme ich folgende Fehlermeldung:

```
java -cp /home/andreas/Desktop/client.jar -Djava.security.policy=/home/andreas/Desktop/policy.all de.hft_stuttgart.verteiltesysteme.ostereier.client.Client
java.rmi.UnmarshalException: error unmarshalling return; nested exception is: 
        java.lang.ClassNotFoundException: de.hft_stuttgart.verteiltesysteme.ostereier.server.RemoteInterface
        at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
        at java.rmi.Naming.lookup(Naming.java:84)
        at de.hft_stuttgart.verteiltesysteme.ostereier.client.Client.main(Client.java:22)
Caused by: java.lang.ClassNotFoundException: de.hft_stuttgart.verteiltesysteme.ostereier.server.RemoteInterface
        at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:247)
        at sun.rmi.server.LoaderHandler.loadProxyInterfaces(LoaderHandler.java:711)
        at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:655)
        at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:592)
        at java.rmi.server.RMIClassLoader$2.loadProxyClass(RMIClassLoader.java:628)
        at java.rmi.server.RMIClassLoader.loadProxyClass(RMIClassLoader.java:294)
        at sun.rmi.server.MarshalInputStream.resolveProxyClass(MarshalInputStream.java:238)
        at java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1531)
        at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1493)
        at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1732)
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
        ... 3 more
```

Verstehe leider nicht warum. Eine Policy gebe ich doch an. Die Datei sieht so aus:

```
// this policy file should only be used for testing and not deployed
grant {
    permission java.security.AllPermission;
};
```

Kann mir jemand weiterhelfen? Bin auch über kleine Tipps dankbar. Bisher hat mir weder Google noch dieses Forum weiterhelfen können. Auch wenn dieses Problem in ähnlicher Form wohl schon öfter aufgetaucht ist.


----------



## Wastl (9. Apr 2007)

leg mal beim Client auch das Package de.hft_stuttgart.verteiltesysteme.ostereier.server an und leg dort das RemoteInterface rein und sag Bescheid ob das funktioniert.


----------



## TheNose (9. Apr 2007)

Vielen Dank! Genau das war mein Problem!


----------



## TheNose (9. Apr 2007)

Eine Frage habe ich doch noch: Ist es möglich diese policy auch fest zu codieren?


----------



## Wastl (9. Apr 2007)

zu deinem ersten Problem nochmal. Das Remote Object muss ja wissen welche Methoden zur Verfügung stehen, daher muss das Interface auch beim Client vorhanden sein. Ob man das Interface nicht auch per RMI anfordern kann weiss ich nicht.

zu deinem zweiten Problem: ja man kann die policy fest eincodieren, eine Datei braucht man allerdings immer noch. du kannst dir lediglich sparen, die Policy datei als Startargument anzugeben. Einfach folgende Zeile in den Server einfügen:

```
System.setProperty("java.security.policy", "PolicyDatei");
```


----------

