我有一个webapp,可以在客户端保存状态。州被累积为Object []
Object state[] = new Object[10];
state[0] = _parent_s_state_array
state[1] = _some_int;
state[2] = _some_POJO;
..
..
然后是
在下一个请求中,这个序列化状态被提交回来,我们反转在服务器端重建状态的步骤。这个策略适用于几百页。
但对于使用具有少量String属性的特定POJO的某个页面,我在反序列化时得到ClassNotFoundException
。需要注意的是,同一个类的对象在不久之前在同一个JVM会话中创建并序列化,因此我们可以排除Class不存在于类路径中。
更多观察
WEB-INF/classes/com/xxx/yyy/
有人可以为调试此问题提供一些指示/策略。
提前致谢。
异常
ERROR [[ACTIVE] ExecuteThread: '5' for queue: 'weblogic.kernel.Default (self-tuning)'] ClassNotFoundException occured restoring StateManager state from serialized form
java.lang.ClassNotFoundException: com.xxx.yyy.TimeParameters
at java.net.URLClassLoader$1.run(URLClassLoader.java:366) ~[na:1.7.0_65]
at java.net.URLClassLoader$1.run(URLClassLoader.java:355) ~[na:1.7.0_65]
at java.security.AccessController.doPrivileged(Native Method) ~[na:1.7.0_65]
at java.net.URLClassLoader.findClass(URLClassLoader.java:354) ~[na:1.7.0_65]
at java.lang.ClassLoader.loadClass(ClassLoader.java:425) ~[na:1.7.0_65]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) ~[na:1.7.0_65]
at java.lang.ClassLoader.loadClass(ClassLoader.java:358) ~[na:1.7.0_65]
at java.lang.Class.forName0(Native Method) [na:1.7.0_65]
at java.lang.Class.forName(Class.java:270) [na:1.7.0_65]
at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:625) ~[na:1.7.0_65]
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1612) ~[na:1.7.0_65]
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1517) ~[na:1.7.0_65]
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771) ~[na:1.7.0_65]
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350) ~[na:1.7.0_65]
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370) ~[na:1.7.0_65]
at org.apache.commons.collections.map.AbstractHashedMap.doReadObject(AbstractHashedMap.java:1212) ~[weblogic.server.merged.jar:12.1.3.0.0]
at org.apache.commons.collections.map.CaseInsensitiveMap.readObject(CaseInsensitiveMap.java:149) ~[weblogic.server.merged.jar:12.1.3.0.0]
类
package com.xxx.yyy;
public class TimeParameters implements Serializable {
/**
*
*/
private static final long serialVersionUID = 5384703411813811209L;
private String yr;
private String qtr;
private String mth;
private String analysisType;
// Getters and Setters
...
...
}
答案 0 :(得分:1)
TLDR;
Apache Commons集合中的一个类在序列化过程中涉及某个地方。由于apache-commons-collections是从Weblogic jar加载的,因此它导致在Application类加载器中搜索所需的类,无法找到它。修复是在org.apache.commons.collections.*
prefer-application-packages
添加到weblogic.xml
详情
我做了一个远程调试器会话来跟踪对Class.forName0(String className, boolean, ClassLoader loader)
的调用。
发现当加载所需的类 时,传递的类加载器具有更深的层次结构
this contains all classes in WEB-INF/classes --> weblogic.utils.classloaders.ChangeAwareClassLoader@6437e3af finder: weblogic.utils.classloaders.CodeGenClassFinder@2cd01c0c annotation: mi.8200@MedicalIntelligence
weblogic.utils.classloaders.FilteringClassLoader@6413df9c finder: weblogic.utils.classloaders.CodeGenClassFinder@54bdae18 annotation:
weblogic.utils.classloaders.GenericClassLoader@5919d25d finder: weblogic.utils.classloaders.CodeGenClassFinder@1265cb83 annotation:
java.net.URLClassLoader@5a88cbff
Application classloader, contains classes from weblogic bundled jars --> sun.misc.Launcher$AppClassLoader@2a9a42ef
sun.misc.Launcher$ExtClassLoader@75a06ec2
当它抛出ClassNotFoundException
它被缩短时 - 只有最后两个条目存在
sun.misc.Launcher$AppClassLoader@2a9a42ef <-- Hierarchy starts at Application classloader
sun.misc.Launcher$ExtClassLoader@75a06ec2
然后,我注意到堆栈跟踪包含以~[weblogic.server.merged.jar:12.1.3.0.0]
结尾的这些行(编辑后的问题以添加更多堆栈跟踪)
at org.apache.commons.collections.map.AbstractHashedMap.doReadObject(AbstractHashedMap.java:1212) ~[weblogic.server.merged.jar:12.1.3.0.0]
at org.apache.commons.collections.map.CaseInsensitiveMap.readObject(CaseInsensitiveMap.java:149) ~[weblogic.server.merged.jar:12.1.3.0.0]
所以Apache commons集合是从weblogic捆绑的jar中加载的,即sun.misc.Launcher$AppClassLoader@2a9a42ef
,这可能会触发错误的类加载器进一步向下传递。因此,在org.apache.commons.collections.*
prefer-application-packages
添加到weblogic.xml
<prefer-application-packages>
...
<package-name>org.apache.commons.collections.*</package-name>
</prefer-application-packages>
有用资源
http(s)://<server-hostname:port>/wls-cat
,显示类加载器树答案 1 :(得分:0)
Java序列化不是完成任务的最佳方式。您最好将其序列化为(比如说)JSON,然后根据需要进行压缩。好的选择是google GSON。或者带有JSON驱动程序的XStream。或杰克逊......