ClassNotFoundException во время десериализации класса just-serializaed


У меня была проблема с десериализацией объекта. Текущий проект имеет архитектуру в стиле плагинов, поэтому у меня есть jars, содержащие файлы классов, которые загружаются во время выполнения. Я не смог десериализовать объект, содержащий класс, который был найден в одном из этих jar, поэтому я написал метод быстрого тестирования, который называется mid-stream, который просто загружает Плагины, создает правильный экземпляр (объект реализует определенный интерфейс, поэтому я могу идентифицировать его через .isAssignableFrom(..) ), сериализует его (что происходит нормально), а затем сразу же пытается десериализовать его.

Я все еще получаю 'ClassNotFoundException'.

Stacktrace:

Jul 21, 2014 4:02:11 PM com.newspinrobotics.auth.MainFrame loadPlugins
SEVERE: null
java.lang.ClassNotFoundException: com.newspinrobotics.auth.plugin.tcpserver.TCPServer
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:270)
at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:625)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1612)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1517)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
at com.newspinrobotics.auth.MainFrame.loadPlugins(MainFrame.java:79)
at com.newspinrobotics.auth.MainFrame.<init>(MainFrame.java:43)
at com.newspinrobotics.auth.MainFrame$6.run(MainFrame.java:539)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
А теперь, прежде чем ты спросишь. Класс TCPServer не содержит несериализуемых полей. В нем есть струны и примитивы. Есть одно поле, которое не подпадает под эти категории, но оно помечено как переходное. Есть даже конструктор no-arg (хотя это не нужно, правильно?). И да он реализует Сериализуемый (сериализация идет нормально).

Меня смущает, как загрузчик классов может не иметь его, поскольку он создает экземпляр объекта всего за несколько строк до десериализации.

Я использую пользовательский загрузчик классов (extends URLClassLoader) для загрузки файлов jar во время выполнения.

Я предоставляю поле public static final long serialVersionUID = XXXXXXXL;.

Редактировать:

Загрузчик классов, на который я ссылаюсь, расширяет URLClassLoader. Он расположен внутри полезного класса, написанного другим человеком, который при дальнейшем рассмотрении на самом деле даже не является модификацией (по какой-то причине ему захотелось расширить его и не делать с ним ничего существенного). Все, что делает утилита, это выбирает отдельные файлы jar и использует URLClassLoader для добавления файлов jar в URLClassLoader через addURL(..) а также загружать классы через loadClass(..). Так что не похоже, что в этой утилите есть что-то гнусное. Я не классный ниндзя. однако, так что я, безусловно, могу дать дополнительную информацию о нем, если это необходимо. На самом деле это всего лишь несколько утилит для загрузки файлов Jar и выбора файлов классов и их загрузки.

Помоги мне StackOverflow, ты моя единственная надежда (возможно).
1 2

1 ответ:

Вы подкласс ObjectInputStream переопределили resolveClass(), чтобы использовать свой пользовательский Classloader? (Пример того, как это делает кто-то другой, хотя и не является прямым ответом на ваш вопрос, см. В разделе ObjectInputStream custom classloader deserialization issue: resolveClass() not called.)