У меня возникла проблема с десериализацией объекта. Текущий проект имеет архитектуру в стиле плагинов, поэтому у меня есть jar-файлы, содержащие файлы классов, которые загружаются во время выполнения. Мне не удалось десериализовать объект, содержащий класс, найденный в одном из этих jar-файлов, поэтому я написал метод быстрого тестирования, который вызывается в середине потока, который только что загрузил плагины, создает экземпляр правильного (объект реализует определенный интерфейс поэтому я могу идентифицировать его с помощью .isAssignableFrom(..) ), сериализовать его (что происходит нормально), а затем сразу же пытается его десериализовать.
Я все еще получаю «ClassNotFoundException».
Трассировки стека:
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 нет несериализуемых полей. В нем есть строки и примитивы. Есть одно поле, которое не попадает в эти категории, но оно помечено как временное. Существует даже конструктор без аргументов (хотя он не нужен, верно?). И да, он реализует Serializable (сериализация проходит нормально).
Я сбит с толку, как загрузчик классов может НЕ иметь его, поскольку он создает экземпляр объекта всего за несколько строк до его десериализации.
Я использую созданный на заказ ClassLoader (расширяет URLClassLoader) для загрузки файлов jar во время выполнения.
Я предоставляю публичный статический окончательный long serialVersionUID = XXXXXXXL; поле.
ИЗМЕНИТЬ:
Загрузчик классов, о котором я говорю, расширяет URLClassLoader. Он расположен внутри служебного класса, написанного другим человеком, который при дальнейшем рассмотрении на самом деле даже не является модификацией (по какой-то причине ему захотелось расширить его и не делать с ним ничего существенного). Все, что делает утилита, это выбирает файлы jar и использует URLClassLoader для добавления файлов jar в URLClassLoader через addURL(..), а также загружает классы через loadClass(..). Так что не похоже, что в этой утилите есть что-то гнусное. Однако я не ниндзя ClassLoader, поэтому я, безусловно, могу дать дополнительную информацию об этом, если это необходимо. На самом деле это всего лишь несколько служебных функций для загрузки файлов Jar, выбора файлов классов и их загрузки.
Помоги мне StackOverflow, ты моя единственная надежда (возможно).
ObjectInputStream
в комментариях к моему ответу не приносит результатов, я предлагаю вам опубликовать код, в котором вы успешно создаете экземплярTCPServer
из своего загрузчика классов, а также код, в котором вы его десериализуете. безуспешно изObjectInputStream
(включая код, в котором вы создаете и настраиваете этотObjectInputStream
). Но, надеюсь, расширениеObjectInputStream
будет всем, что вам нужно. - person Tim   schedule 22.07.2014