在反序列化just-serializaed类期间的ClassNotFoundException

时间:2014-07-21 20:41:01

标签: java serialization deserialization classloader classnotfoundexception

我遇到了反序列化对象的问题。当前项目有一个插件式架构,所以我的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文件。

我确实提供了一个公共静态最终的长版serialVersionUID = XXXXXXXL;字段。

修改

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

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

1 个答案:

答案 0 :(得分:2)

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