java.io.NotSerializableException in Weblogic cluster



我们有一个带有几个节点的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实现所有的类

相关内容

  • 没有找到相关文章

最新更新