java - org.apache.commons.lang.SerializationException : java. lang.ClassNotFoundException 异常

标签 java spring osgi deserialization classloader

我正在使用 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)

人们说配置文件不在类路径中。如果那是真的,错误就会发生在“new Profile()”上。我说得对吗?

我刚找到一个解决方法:

profile = (EveSuccessCriteriaProfile) SerializationUtils.deserialize(payload2);

替换为

InputStream fis = null;
fis = new ByteArrayInputStream(payload2);
ObjectInputStream o = new ObjectInputStream(fis);
profile = (Profile) o.readObject();

一切正常

最佳答案

问题在于,在 OSGi 中,加载所有类的类加载器不止一次。每个包有一个类加载器。因此,如果您执行 Profile.class.getClassLoader(),您将获得包含 Profile 的包的类加载器。如果你执行 SerializationUtils.class.getClassLoder() 那么你将获得 commons.lang 包的类加载器。由于 commons.lang 没有针对您的包配置文件的 Import-Package,因此它不会看到它。 因此,如果 SerializationUtils.deserialize 使用它自己的类加载器来加载 Profile 类,它将找不到它。

我很确定它会尝试使用 ThreadContext 类加载器来加载用户类。所以这可能有助于做 Thread.currentThread().setContextClassLoader(Profile.class.getClassLoader()); 在调用 SerializationUtils.deserialize 之前。

但这只是一种解决方法。应该增强反序列化调用以接受 ClassLoader 作为第二个参数。所以不要养成将 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这应该允许在没有伙伴类加载或类似的情况下干净地进行反序列化。

关于java - org.apache.commons.lang.SerializationException : java. lang.ClassNotFoundException 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33407091/

相关文章:

java - 在 Spring Data Rest 中检索实体的 URI 和 Collection Rel

java - 如何在 SpringDM 中将 bundleContext 引用传递给 bean

java - URL、扫描器和分隔符 : How does this Java Line of Code Works?

java - 将一个jar文件添加到另一个jar文件中

java - 在java中使用AVL树

java - 在 Spring 数据实体中填充 "created"列

java - 在子线程中访问 HttpServletRequest 请求

java - osgi刷新应该什么时候进行?

OSGi 功能卸载有效,但 bundle 仍然安装

java - 为什么日志包含使用 logback 的空字符(孔)