java.rmi.UnmarshalException: возврат ошибки отмены сопоставления; вложенное исключение: java.lang.Исключение ClassNotFoundException:

#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, она предназначена именно для этой ситуации.