I am trying to some pretty basic RMI:
// Context namingContext = new InitialContext();
Registry reg = LocateRegistry.createRegistry(9999);
for ( int i = 0; i < objs.length; i++ ) {
int id = objs[i].getID();
// namingContext.bind( "rmi:CustomObj" + id , objs[i] );
reg.bind( "CustomObj" + id , objs[i] );
}
That works without a hitch, but for future purposes, I need to use InitialContext
.
Context namingContext = new InitialContext();
for ( int i = 0; i < objs.length; i++ ) {
int id = objs[i].getID();
namingContext.bind( "rmi:CustomObj" + id , objs[i] );
}
But I cannot get this to work. I have started rmiregistry
from the command line. Is there an equivalent of LocateRegistry.createRegistry(int)
? Or some other way to start the RMI registry / registry used by InitialContext
from inside my class? (Instead of the command line)
Stack trace:
javax.naming.CommunicationException [Root exception is java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: bguiz.scratch.network.eg.Student]
at com.sun.jndi.rmi.registry.RegistryContext.bind(RegistryContext.java:126)
at com.sun.jndi.toolkit.url.GenericURLContext.bind(GenericURLContext.java:208)
at javax.naming.InitialContext.bind(InitialContext.java:400)
at bguiz.scratch.RMITest.main(RMITest.java:29)
Caused by: java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: bguiz.scratch.CustomObj
at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:396)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:250)
....(truncated)
EDIT: I will delete my own question in a couple of days, as there seems to be no answer to this (I haven't been able to figure it out myself). Last call for any biters!
After much tinkering, I've solved the problem. FYI, here's what it was:
The ClassNotFoundException
is getting thrown because of RMI registry has its own classpath. It doesn't matter that the class containing the InitialContext
has the custom objects on its classpath - The RMI registry must be initialised such that the custom objects are on its classpath as well.
To do this set the classpath
environment value on the comman line prior to starting rmiregistry
. If this classpath contains the custom object's class, the ClassNotFoundException
is not thrown, and subsequently ServerException
and `CommunicationException' are avoided.