我正在使用org.apache.commons.lang.SerializationUtils,但是我收到了一个错误。如果您需要更多信息,我是Java新手,请告诉我 代码:
Profile profile2 = new Profile();
profile2.setFileName(path);
profile2.setStatus("UPLOADED");
byte[] payload2 = SerializationUtils.serialize(profile2);
profile = (Profile) SerializationUtils.deserialize(payload2);
运行时错误输出:
org.apache.commons.lang.SerializationException: java.lang.ClassNotFoundException: com.xxx.xxx.Profile
at org.apache.commons.lang.SerializationUtils.deserialize(SerializationUtils.java:166)
at org.apache.commons.lang.SerializationUtils.deserialize(SerializationUtils.java:193)
人们说Profile不在classpath中。如果确实如此,则会在“new Profile()”上发生错误。我是对的吗?
我刚刚找到了解决方法:
profile = (EveSuccessCriteriaProfile) SerializationUtils.deserialize(payload2);
替换为
InputStream fis = null;
fis = new ByteArrayInputStream(payload2);
ObjectInputStream o = new ObjectInputStream(fis);
profile = (Profile) o.readObject();
一切正常
答案 0 :(得分:5)
问题是在OSGi中不仅有一次加载所有类的类加载器。每个包有一个类加载器。因此,如果您执行Profile.class.getClassLoader(),您将获得包含Profile的包的类加载器。如果您执行SerializationUtils.class.getClassLoder(),那么您将获得commons.lang包的类加载器。由于commons.lang没有一个Import-Package,因为包中的Profile不会看到它。 因此,如果SerializationUtils.deserialize使用自己的类加载器来加载Profile类,它将无法找到它。
我很确定它会尝试使用ThreadContext类加载器来加载用户类。所以它可能有所帮助
在调用SerializationUtils.deserialize之前Thread.currentThread().setContextClassLoader(Profile.class.getClassLoader());
。
这只是一种解决方法。应该增强反序列化调用以接受ClassLoader作为第二个参数。因此,不要进入habbit,将ContextClassLoader视为最佳实践。
不幸的是,SerializationUtils在OSGi中不起作用。您必须等待解决此问题:https://issues.apache.org/jira/browse/LANG-1049
您应该尝试使用https://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/input/ClassLoaderObjectInputStream.html,以便在没有伙伴类加载或类似情况的情况下干净地进行反序列化。