Reputation: 23
I'm currently developing a system that loads classes via rmi. This system uses a classloader that communicates with the server in order to get the classes. The code is as follows.
Server:
import rocks.squareRock;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class Server extends UnicastRemoteObject
implements RemInterface {
public Server() throws RemoteException {
super();
}
public static void main(String argv[]) {
try {
Server serv = new Server();
Naming.rebind("RockServer", serv);
} catch (Throwable t) {
t.printStackTrace();
}
}
public Class<?> getRockClass(String type) {
if (type.equals("squareRock"))
return squareRock.class;
else
return null;
}
}
Client:
import rocks.Rock;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
public class Client {
RemInterface reminterface = null;
RockLoader rl = null;
public Client() {
String strName = "rmi://127.0.0.1/RockServer";
try {
reminterface = (RemInterface) Naming.lookup(strName);
rl = new RockLoader(reminterface);
} catch (RemoteException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
}
loadRock("squareRock");
}
public Rock loadRock(String rock) {
try {
return (Rock) rl.loadClass(rock, false).newInstance();
} catch (Throwable t) {
return null;
}
}
}
Interface:
public interface RemInterface {
public Class<?> getRockClass(String type) throws RemoteException;
}
RockLoader:
import java.io.Serializable;
public class RockLoader extends ClassLoader implements Serializable {
private RemInterface reminterface = null;
public RockLoader(RemInterface reminterface) {
super();
this.reminterface = reminterface;
}
@Override
protected synchronized Class<?> loadClass(String className, boolean resolve)
throws ClassNotFoundException {
try {
return reminterface.getRockClass(className);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
The error I'm getting with this is (client-side):
java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
java.lang.ClassNotFoundException: SquareRock
This confuses me, as I'm not unmarshalling a SquareRock instance, but a Class. The only thought I have is that my classloader might be wrong.
Upvotes: 1
Views: 2662
Reputation: 310850
It doesn't matter whether it's a Class or an object. The receiving JVM must have that class in its classpath, unless you are using the RMI codebase feature. What you are doing is basically trying to implement the codebase feature yourself. You can't do that.
Upvotes: 1