Connect to Java RMI Server from Jython



  • I have a Java (version 1.5) RMI server which I need to connect to via Jython.  This seems like it should be easy, however, I keep getting an exception of the following variety:

    java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
        java.lang.ClassNotFoundException: RawDBServer
        at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
        at java.rmi.Naming.lookup(Unknown Source)


    Where RawDBServer is an interface which extends java.rmi.Remote and has an implementation which extends java.rmi.UnicastRemoteObject which is bound to the RMI registry appropriately.  Interestingly, if I create a small client in Java, I'm able to connect with the following code:

    String objName = "rmi://" + hostname + ":" + port + "/" + RawDBServer.SERVER_NAME;
    RawDBServer server = (RawDBServer) Naming.lookup(objName);
    if (server != null) {
        System.out.println("Connected")
    }

     However, if I use the following code in my jython client (with the same values for the hostname and port), I get the aforementioned exception:

    objName = "rmi://" + rawDBHostname + ":" + rawDBPort + "/" + RawDBServer.SERVER_NAME
    DB_SERVICE = Naming.lookup(objName);

    Does anyone have any experience, or any resources about connecting to a Java RMI server from jython?  Any help would be appreciated.  I know in previous versions of Java you needed to do a special compilation for remote classes, but I thought that had gone away in Java 1.5



  • I assume you've checked the classpath and you are using Java 1.5 on the client side.

    You should be able to take the code that works in Java and run it in Java in Jython; i.e. use pure Java classes instead of Jython classes that inherit from Java classes.

    In the Jython version did you write a Jython version of RawDBServer?  If so, can you instead take your Java version (RawDBServer.java), compile it to RawDBServer.class, and include it in the Jython classpath?

    (I really don't know anything about RMI.  I just know a little about Jython.)

     



  • Try replacing the naming lookup in the jython code with DB_SERVICE = new JythonDummyDBService, which is a jython class you'll have to write that implements the existing RawDBServer interface.  That'll prove that the jython app's classloader can see your RawDBServer interface...  If that works, then two things follow:

    1. Naming.lookup or one of its callees is creating its own classloader (likely)

    2. That classloader is isolated from your app's classloader.  It's been a while since I did RMI programming, but there are some system properties RMI uses to locate classes for RMI; make sure those are set up correctly (this used to be a giant pain in the arse).
     



  • Ended up using the working Java client up as a delegate to the RawDBServer stub and creating it directly in Jython.  Worked just fine.


Log in to reply