我们有一个带有几个节点的Weblogic集群,在那里我们部署了一个基于JSF、Richfaces、Hibernate和Spring的web应用程序。
应用程序似乎运行良好,但我们在日志中有以下错误,每2-3秒:
<Jun 25, 2015 6:08:14 PM CEST> <Error> <Cluster> <BEA-000126> <All session objects should be serializable to replicate. Check the objects in the session. Failed to replicate a non-serializable object.
java.rmi.MarshalException: failed to marshal update(Lweblogic.cluster.replication.ROID;ILjava.io.Serializable;Ljava.lang.Object;); nested exception is:
java.io.NotSerializableException: <Some @Service class name here>
at weblogic.rjvm.BasicOutboundRequest.marshalArgs(BasicOutboundRequest.java:92)
at weblogic.rmi.internal.BasicRemoteRef.invoke(BasicRemoteRef.java:300)
at weblogic.cluster.replication.ReplicationManager_12120_WLStub.update(Unknown Source)
at sun.reflect.GeneratedMethodAccessor773.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
我们在本地没有集群来测试,所以我添加了一段代码来序列化来自一个控制器的对象,看看序列化在本地环境中是否正常:
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ObjectOutputStream outputObj;
try {
outputObj = new ObjectOutputStream(outputStream);
outputObj.writeObject(service);
outputObj.close();
outputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
service
在这里是堆栈跟踪中显示的服务类的一个实例,用@Autowired
注释。
我所遵循的解决这个问题的方法是为NotSerializableException设置一个断点,并实现java.io.Serializable
,并在调试中抱怨的所有类中添加生成的串行版本UID。由于它们很多,我最终对所有服务(用@Service
注释)和所有存储库类(@Repository
)都这样做了。那些类不再抱怨,但现在我有JaxWsClientProxy
抱怨同样的。
我不能触摸这个类,因为它在我的应用程序的外部。此外,我没有在我的代码中找到任何对它的引用,所以我可以将它设置为transient。即使我找到了参考资料,我也不确定这样做是否安全。
应用程序运行良好,因此有人建议可以忽略此异常。另一方面,我想知道服务/存储库类是否应该在WS集群上复制,以及正确的方法是什么。
编辑:根据@sunrise76评论:
你能看看下面的链接吗?cxf.547215.n5.nabble.com/session-management-td549278.html。我认为你的session不应该是jar中类的类型- sunrise76
我不知道如何使用你传递给我的信息,所以我检查了谁正在实例化这个JaxWsClientProxy
类。当实例化一个名为clientPEndpoint
的bean和另一个名为clientGEndpoint
的bean时,它被证明是Spring。
我检查了项目,发现这是在XML中,我们有Apache Camel配置:
<jaxws:client id="clientPEndpoint"
address="${ws.endPoint}"
serviceClass="<some service class>"
endpointName="s:Connector" serviceName="s:ConnectorPortType"
xmlns:s="<some namespace>">
<jaxws:outInterceptors>
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken" />
<entry key="user" value="${ws.user}" />
<entry key="passwordType" value="PasswordText" />
<entry key="passwordCallbackRef">
<ref bean="myPasswordCallback" />
</entry>
</map>
</constructor-arg>
</bean>
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" id="logOut" parent="abstractLoggingInterceptor" />
</jaxws:outInterceptors>
<jaxws:inInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor" id="logIn" parent="abstractLoggingInterceptor" />
</jaxws:inInterceptors>
<jaxws:dataBinding>
<bean class="org.apache.cxf.jaxb.JAXBDataBinding">
<property name="extraClass">
<list>
<value><some ObjectFactory class></value>
..........
</list>
</property>
</bean>
</jaxws:dataBinding>
</jaxws:client>
<jaxws:client id="clientGEndpoint"
address="${g.ws.endPoint}"
serviceClass="<some service class>"
endpointName="s:WebServiceService" serviceName="s:WebService"
xmlns:s="<some namespace>">
<jaxws:outInterceptors>
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken" />
<entry key="user" value="${g.ws.user}" />
<entry key="passwordType" value="PasswordText" />
<entry key="passwordCallbackRef">
<ref bean="gPasswordCallback" />
</entry>
</map>
</constructor-arg>
</bean>
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" id="logOut" parent="abstractLoggingInterceptor" />
</jaxws:outInterceptors>
<jaxws:inInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor" id="logIn" parent="abstractLoggingInterceptor" />
</jaxws:inInterceptors>
<jaxws:dataBinding>
<bean class="org.apache.cxf.jaxb.JAXBDataBinding">
<property name="extraClass">
<list>
<value><some ObjectFactory class></value>
</list>
</property>
</bean>
</jaxws:dataBinding>
</jaxws:client>
我想说这个配置使Spring创建JaxWsClientProxy
的实例,但我不完全确定。
无论如何,正如m.d inum所说,我不确定我是否应该序列化服务/dao的实例,所以也许我应该瞄准一些Weblogic配置。
你应该检查一下可序列化的class对象(service),它里面的变量有可序列化的能力,例如int可以,而ImageView不能。您应该在此变量之前添加transient。当你想要序列化一个没有被标记为Serializable的对象时抛出。你应该用serializable实现所有的类