Search code examples
javapluginsrmi

special things to do when using rmi + plugins


I have an application FooApplication (code in foo.jar) with a plugin BarPlugin (code in foo-bar-plugin.jar). The application instantiates an instance of the plugin dynamically. It works great.

FooApplication has some functionality accessible via an RMI interface FooRemote. That also works great, except for one thing. FooRemote has a method to access Remote objects exported by plugins, and I get an java.rmi.UnmarshalException when I try to hand out one of those plugins to an RMI client.

public interface FooRemote extends Remote
{
    /* other methods */
    public RemoteControl getPluginRemoteControl(int i) throws RemoteException;
}
/** just a named Remote object for debugging purposes */
public interface RemoteControl extends Remote
{
    public String getName() throws RemoteException;
}

What I am doing in my FooRemoteImpl is the following:

/* just a test object */
private static class RC0 extends UnicastRemoteObject implements RemoteControl 
{
    public RC0() throws RemoteException { super(); }
    @Override public String getName() throws RemoteException { return "RC0"; }
}

@Override public RemoteControl getPluginRemoteControl(int i) 
       throws RemoteException 
{
    int j = i;
    if (j <= 0)
        return new RC0();

    Collection<RemoteControl> rclist = this.model.getApplicationPluginRemotes();
    for (RemoteControl rc : rclist)
    {
        if (--j == 0)
            return rc;
    }
    return null;
}

When I call FooRemote.getPluginRemoteControl(0), it hands out an instance of my dummy class RC0, and works fine from a client. When I call FooRemote.getPluginRemoteControl(1), it tries to hand out one of the real plugin remotes, and it fails:

??? Java exception occurred:
java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
    java.lang.ClassNotFoundException: com.example.plugin.BarPluginRemoteControl (no security manager: RMI class loader disabled)

    at sun.rmi.server.UnicastRef.invoke(Unknown Source)

    at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)

    at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)

    at $Proxy5.getPluginRemoteControl(Unknown Source)

Caused by: java.lang.ClassNotFoundException: com.example.plugin.BarPluginRemoteControl (no security manager: RMI class loader disabled)

[ more stuff deleted ] 

What gives?


Solution

  • The RMI Registry also needs the classes on it's own classpath, in case you are running it in a separate VM. I remember wasting too much time learning this the hard way.

    Glad I could help!

    edit: apparently this is not the correct approach, see answer by the commenter.