Search code examples
javaregistryrmiinitial-context

Java RMI InitialContext: Equivalent of LocateRegistry.createRegistry(int)?


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!


Solution

  • 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.