org.apache.commons.lang.SerializationException: java.lang.ClassNotFoundException
org.apache.commons.lang.SerializationException: java.lang.ClassNotFoundException
我正在使用 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 中,不仅 classloader 加载了所有 classes。每个包有一个 classloader。因此,如果您执行 Profile.class.getClassLoader(),您将获得包含 Profile 的包的 classloader。如果你执行 SerializationUtils.class.getClassLoder() 那么你将获得 commons.lang 包的 classloader。由于 commons.lang 没有针对您的包配置文件的 Import-Package,因此它不会看到它。
因此,如果 SerializationUtils.deserialize 使用它自己的 classloader 来加载配置文件 class,它将找不到它。
我很确定它会尝试使用 ThreadContext classloader 来加载用户 class。所以这可能有助于做
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,它应该允许在没有伙伴 class 加载或类似的情况下干净地进行反序列化。
我正在使用 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 中,不仅 classloader 加载了所有 classes。每个包有一个 classloader。因此,如果您执行 Profile.class.getClassLoader(),您将获得包含 Profile 的包的 classloader。如果你执行 SerializationUtils.class.getClassLoder() 那么你将获得 commons.lang 包的 classloader。由于 commons.lang 没有针对您的包配置文件的 Import-Package,因此它不会看到它。 因此,如果 SerializationUtils.deserialize 使用它自己的 classloader 来加载配置文件 class,它将找不到它。
我很确定它会尝试使用 ThreadContext classloader 来加载用户 class。所以这可能有助于做
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,它应该允许在没有伙伴 class 加载或类似的情况下干净地进行反序列化。