#classloader #rmi
#classloader #rmi
Вопрос:
У меня следующая ситуация:
Используя 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.Подключаемый модуль INDEX.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.java:176)
Вызвано: java.lang .Исключение ClassNotFoundException: pt.ua.dicoogle.Подключаемый модуль INDEX.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.ввод.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(собственный метод) в sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) в sun.отразить.Делегирование methodaccessorimpl.invoke(делегирование methodaccessorimpl.java:25) в java.lang.reflect.Метод.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)
Есть какие-либо предложения?
Ответ №1:
Вам нужно будет вызвать удаленный метод в контексте этого загрузчика классов. Не очень хорошая схема. Внимательно посмотрите на функцию кодовой базы RMI, она предназначена именно для этой ситуации.