只有在将共享库添加到IBM WebSphere实例(版本8.5.xx)上的应用程序中时,我才会收到以下错误。其目标是将一些应用程序之间的大量共享库( war )移动到服务器上的共享库,以减少应用程序的war大小。从我所看到的来看,war文件大小是否减小并不重要,每当添加这个共享库时,我们都会看到以下错误。
org.springframework.remoting.RemoteAccessException: Could not deserialize result from HTTP invoker remote service [<URL>]; nested exception is java.lang.ClassNotFoundException: com.example.models.ExampleModel
at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.convertHttpInvokerAccessException(HttpInvokerClientInterceptor.java:221)
at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.invoke(HttpInvokerClientInterceptor.java:153)
at com.example.configuration.LoggingHttpInvokerProxyFactoryBean.invoke(LoggingHttpInvokerProxyFactoryBean.java:28)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy305.getSomeListOfObjects(Unknown Source)
...
...
...
Caused by: java.lang.ClassNotFoundException: com.example.models.ExampleModel
at java.lang.Class.forNameImpl(Native Method)
at java.lang.Class.forName(Class.java:403)
at java.io.ClassCache$FutureValue.get(ClassCache.java:177)
at java.io.ClassCache.get(ClassCache.java:148)
at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:834)
at org.springframework.core.ConfigurableObjectInputStream.resolveClass(ConfigurableObjectInputStream.java:78)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:2017)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1900)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2194)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1722)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2439)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2363)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2221)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1722)
at java.io.ObjectInputStream.readObjectImpl(ObjectInputStream.java:540)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:475)
at org.springframework.remoting.httpinvoker.AbstractHttpInvokerRequestExecutor.doReadRemoteInvocationResult(AbstractHttpInvokerRequestExecutor.java:291)
at org.springframework.remoting.httpinvoker.AbstractHttpInvokerRequestExecutor.readRemoteInvocationResult(AbstractHttpInvokerRequestExecutor.java:242)
at org.springframework.remoting.httpinvoker.HttpComponentsHttpInvokerRequestExecutor.doExecuteRequest(HttpComponentsHttpInvokerRequestExecutor.java:248)
at org.springframework.remoting.httpinvoker.AbstractHttpInvokerRequestExecutor.executeRequest(AbstractHttpInvokerRequestExecutor.java:137)
at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.executeRequest(HttpInvokerClientInterceptor.java:202)
at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.executeRequest(HttpInvokerClientInterceptor.java:184)
at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.invoke(HttpInvokerClientInterceptor.java:150)下面是一个类似的示例,展示了模型类在较小规模上的外观。我主要想指出的是,它确实实现了可序列化(使用默认的serialVersionUID):
package com.example.models.ExampleModel;
public class ExampleModel implements Serializable {
private static final long serialVersionUID = 1L;
private String customerNumber = "";
}任何调试的想法至少都会得到极大的赞赏。我还想指出,当未将共享库添加到服务器上的应用程序时,调用此远程处理方法工作得很好,但在添加共享库时,调用该远程处理方法似乎不起作用。此外,服务器上的共享库没有包含无法找到的类的jar。包含无法找到的类的jar在我的WEB-INF/lib文件夹中,我已经验证了它是否要安装在服务器上。
发布于 2020-01-09 23:50:20
这看起来像是类加载器层次结构的问题,其中由应用程序(EAR)类加载器加载的类试图加载web模块(WAR)加载器中打包的类。我相信ObjectInputStream的resolveClass()方法正在使用它的调用者的类加载器来加载失败的类,并且我在这里还假设您的Spring类在共享库中。
在Java应用程序中,EAR和WAR有不同的类装入器,EAR的装入器充当父装入器。当共享库与WebSphere中的应用程序相关联时,其内容将被添加到EAR加载器的类路径中。如果共享库中的类需要对WAR中打包的类可见,这是一个问题,因为父加载器不能“看到”它们的子类。WebSphere允许您将共享库与应用程序关联,或者与应用程序中的一个或多个web模块关联,这将更改库的类路径附加到哪个类加载器。
假设我正确理解了resolveClass的打包和行为,我认为解决方案应该相当简单-不是将共享库与应用程序关联,而是将其与包含未被找到的类的web模块关联(请注意,您还需要删除EAR级别的关联,否则它将从那里加载Spring类,同样的问题也会发生)。这将把WAR路径和共享库路径放到同一个类加载器中,从而消除了层次结构问题。
请注意,即使我的假设是正确的,如果您为共享库选择了“使用隔离类加载器”选项,该解决方案也不会起作用-该设置创建了一个单独的类加载器,该类加载器作为与其关联的WAR/EAR的父类进行操作,因此即使它与WAR相关联,它仍然不能看到WAR中的类。如果存在需要独立类加载行为的jars,则必须将WAR类重新定位到共享库中,或者将Spring内容放回WAR中。
发布于 2020-01-11 04:50:59
@Jarid提供了详细的解决方案。如果您寻求其他调试步骤,请阅读他的解决方案。
简而言之,我有一个包含Spring Framework jar的共享库,该库同时连接到应用程序和web模块。一旦共享库从应用程序中删除,并且仅附加到web模块,应用程序就开始正常工作,并能够反序列化结果。
https://stackoverflow.com/questions/59654605
复制相似问题