ClassNotFoundException during Deserialization of a just-serializaed class

这一生的挚爱 提交于 2020-01-04 09:06:28

问题


I was having an issue with deserializing an object. The current project has a plugin-style architecture, so I have jars that contain class files that are loaded at runtime. I was unable to deserialize an object that contained a class that was found in one of those jars, so I wrote a quick test method that gets called mid-stream that just loaded the plugins, instantiates the correct one (the object implements a particular interface so I can identify it via .isAssignableFrom(..) ), serializes it (which happens fine), and then immediately tries to deserialize it.

I still get a '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)

Now, before you ask. The TCPServer class has no non-serializable fields in it. It has Strings and primitives in it. There is one field that does not fall into those categories but it is marked transient. There is even a no-arg constructor (though that is not needed, correct?). And yes it implements Serializable (the serialization goes fine).

I am confused how the classloader could possibly NOT have it since it instantiates the object only a few lines before it deserializes it.

I do use a custom-made ClassLoader (extends URLClassLoader) to load the jar files at runtime.

I do provide a public static final long serialVersionUID = XXXXXXXL; field.

EDIT:

The Class loader I am referring to extends URLClassLoader. It's located inside a utility class written by another person that upon further inspection actually is not really even a modification (for some reason he felt like extending it and not really doing anything of substance to it). All the utility does is pick apart jar files, and use the URLClassLoader to add the jar files into the URLClassLoader via addURL(..) and also load the classes via loadClass(..). So it does not seem like there's anything nefarious in this utility. I am no ClassLoader ninja however, so I can certainly give further info on it if needed. It's really just a few utility functions for loading Jar files and picking out class files and loading them.

Help me StackOverflow, you're my only hope (maybe).


回答1:


Did you subclass ObjectInputStream to override resolveClass() to use your custom Classloader? (For an example of someone else doing this, though not a direct answer to your question, see ObjectInputStream custom classloader deserialization issue: resolveClass() not called.)



来源:https://stackoverflow.com/questions/24874331/classnotfoundexception-during-deserialization-of-a-just-serializaed-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!