Reputation: 23
I have the following situation:
Using RMI, i noticed that under a specific situation, the RMI client did not have the class whose instance was sent via RMI. So, I sent the class in the shape of Byte [] and then loaded it with a class loader i defined.
The code in the client side is something like:
pp = plugins.getPanelClasses(); //RMI method
panelClassLoader pcl = new panelClassLoader(); //simple class loader defined by me
String name = pcl.defineClass(pp);
Then, i ask in the client side by the instance of the class loaded:
HashMap<String, PluginPanel> panels = null;
try
{
panels = plugins.getSettingsPanels();
} catch (RemoteException ex)
{
Logger.getLogger(ServerOptions.class.getName()).log(Level.SEVERE, null, ex);
}
PluginPanel is an interface whose implementing classes are not always in the client...
and the class loader is:
private class panelClassLoader extends ClassLoader
{
public panelClassLoader(ClassLoader parent)
{
super(parent);
}
public panelClassLoader()
{
super(getSystemClassLoader());
}
public String defineClass(byte[] b)
{
Class c = super.defineClass(null, b, 0, b.length);
resolveClass(c);
return c.getName();
}
}
Nevertheless, I'm stuck with the following error: java.rmi.UnmarshalException: error unmarshalling return; nested exception is: java.lang.ClassNotFoundException: pt.ua.dicoogle.IndexPlugin.CPanel (no security manager: RMI class loader disabled) at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:178) at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:178) at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:132) at $Proxy22.getSettingsPanels(Unknown Source) at pt.ua.dicoogle.rGUI.client.windows.ServerOptions.(ServerOptions.java:176)
Caused by: java.lang.ClassNotFoundException: pt.ua.dicoogle.IndexPlugin.CPanel (no security manager: RMI class loader disabled) at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:375) at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:165) at java.rmi.server.RMIClassLoader$2.loadClass(RMIClassLoader.java:620) at java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:247) at sun.rmi.server.MarshalInputStream.resolveClass(MarshalInputStream.java:197) at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1574) at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1731) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350) at java.util.HashMap.readObject(HashMap.java:1030) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:974) at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350) at sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:306) at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:155)
Any sugestion?
Upvotes: 0
Views: 8256
Reputation: 310913
You would have to call the remote method in the context of that class loader. Not a good scheme. Have a good look at the RMI codebase feature, it is designed for exactly this situation.
Upvotes: 2