java - 刚刚序列化的类的反序列化期间出现 ClassNotFoundException

标签 java serialization deserialization classloader classnotfoundexception

我在反序列化对象时遇到问题。当前项目具有插件式架构,因此我有包含在运行时加载的类文件的 jar。我无法反序列化一个包含在其中一个 jar 中找到的类的对象,因此我编写了一个快速测试方法,该方法被称为中流,它刚刚加载了插件,实例化了正确的插件(该对象实现了一个特定的接口(interface)所以我可以通过 .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 类中没有不可序列化的字段。它里面有字符串和原语。有一个字段不属于这些类别,但它被标记为 transient 。甚至还有一个无参数构造函数(尽管不需要,对吗?)。是的,它实现了 Serializable(序列化很顺利)。

我很困惑类加载器怎么可能没有它,因为它在反序列化之前只实例化了对象几行。

我确实使用定制的 ClassLoader(扩展 URLClassLoader)在运行时加载 jar 文件。

我确实提供了一个 public static final long serialVersionUID = XXXXXXXL;字段。

编辑:

我指的类加载器扩展了 URLClassLoader。它位于另一个人编写的实用程序类中,经过进一步检查实际上什至不是真正的修改(出于某种原因,他想扩展它而不是真正对它做任何实质性的事情)。该实用程序所做的只是挑选 jar 文件,并使用 URLClassLoader 通过 addURL(..) 将 jar 文件添加到 URLClassLoader 中,并通过 loadClass(..) 加载类。因此,该实用程序似乎没有任何恶意。然而,我不是 ClassLoader 高手,所以如果需要,我当然可以提供更多信息。它实际上只是一些用于加载 Jar 文件和挑选类文件并加载它们的实用函数。

帮助我 StackOverflow,你是我唯一的希望(也许)。

最佳答案

您是否将 ObjectInputStream 子类化以覆盖 resolveClass() 以使用您的自定义 Classloader? (有关其他人这样做的示例,虽然不是对您问题的直接回答,但请参阅 ObjectInputStream custom classloader deserialization issue: resolveClass() not called。)

关于java - 刚刚序列化的类的反序列化期间出现 ClassNotFoundException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24874331/

相关文章:

java - PowerMockito。模拟静态方法。为什么 PowerMockito#stub 不起作用?

java - 使用 Jackson 将巨大的 JSON 响应反序列化为 POJO 的最有效方法是什么?

java - 为什么左侧的类型被忽略 - Jackson 反序列化

java - 当我尝试解析字符串时,我的应用程序崩溃了

java - 和引擎更新

web-services - 是否有适用于 VB6/VBA 的 JSON 解析器?

c++ - 结构中浮点 vector 的序列化

java - 如何使用 Gson 反序列化继承公共(public)基类的类型?

java.lang.UnsupportedOperationException : not yet implemented for SQL queries

javascript - 使用 Newtonsoft.Json 删除引号转义