【发布时间】:2023-10-25 11:28:02
【问题描述】:
我有以下情况:
使用 RMI,我注意到在特定情况下,RMI 客户端没有通过 RMI 发送实例的类。所以,我以 Byte [] 的形式发送类,然后用我定义的类加载器加载它。
客户端的代码是这样的:
pp = plugins.getPanelClasses(); //RMI method
panelClassLoader pcl = new panelClassLoader(); //simple class loader defined by me
String name = pcl.defineClass(pp);
然后,我通过加载的类的实例在客户端询问:
HashMap<String, PluginPanel> panels = null;
try
{
panels = plugins.getSettingsPanels();
} catch (RemoteException ex)
{
Logger.getLogger(ServerOptions.class.getName()).log(Level.SEVERE, null, ex);
}
PluginPanel 是一个接口,其实现类并不总是在客户端...
类加载器是:
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();
}
}
不过,我遇到了以下错误: java.rmi.UnmarshalException:错误解组返回;嵌套异常是: java.lang.ClassNotFoundException: pt.ua.dicoogle.IndexPlugin.CPanel(无安全管理器:RMI 类加载器已禁用) 在 sun.rmi.server.UnicastRef.invoke(UnicastRef.java:178) 在 java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:178) 在 java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:132) 在 $Proxy22.getSettingsPanels(未知来源) 在 pt.ua.dicoogle.rGUI.client.windows.ServerOptions.(ServerOptions.java:176)
原因:java.lang.ClassNotFoundException: pt.ua.dicoogle.IndexPlugin.CPanel(无安全管理器:RMI 类加载器已禁用) 在 sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:375) 在 sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:165) 在 java.rmi.server.RMIClassLoader$2.loadClass(RMIClassLoader.java:620) 在 java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:247) 在 sun.rmi.server.MarshalInputStream.resolveClass(MarshalInputStream.java:197) 在 java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1574) 在 java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495) 在 java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1731) 在 java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328) 在 java.io.ObjectInputStream.readObject(ObjectInputStream.java:350) 在 java.util.HashMap.readObject(HashMap.java:1030) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 在 java.lang.reflect.Method.invoke(Method.java:597) 在 java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:974) 在 java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848) 在 java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752) 在 java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328) 在 java.io.ObjectInputStream.readObject(ObjectInputStream.java:350) 在 sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:306) 在 sun.rmi.server.UnicastRef.invoke(UnicastRef.java:155)
有什么建议吗?
【问题讨论】:
标签: classloader rmi