代码之家  ›  专栏  ›  技术社区  ›  Aaron Marcus

刚刚序列化的类的反序列化期间发生ClassNotFoundException

  •  3
  • Aaron Marcus  · 技术社区  · 10 年前

    我在反序列化对象时遇到问题。当前项目有一个插件风格的架构,所以我有包含运行时加载的类文件的jar。我无法反序列化包含在其中一个jar中找到的类的对象,因此我编写了一个快速测试方法,该方法被称为midstream,它刚刚加载了插件,实例化了正确的插件(该对象实现了一个特定的接口,因此我可以通过.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文件。

    我确实提供了一个公共静态最终长序列VersionUID=XXXXXXX L;领域

    编辑:

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

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

    1 回复  |  直到 10 年前
        1
  •  2
  •   Community c0D3l0g1c    7 年前

    你是子类吗 ObjectInputStream 以覆盖 resolveClass() 使用您的自定义 Classloader ? (对于其他人这样做的示例,尽管不是对您问题的直接回答,请参见 ObjectInputStream custom classloader deserialization issue: resolveClass() not called .)