Serialized class com.xxx.xxxService must implement java.io.Serializable

大家好,我是烤鸭:

    使用dubbo的时候,遇到如下的问题。
    Serialized class com.xxx.xxxService must implement java.io.Serializable

1.  异常

dubbo无论使用哪个协议传递参数的时候,都需要参数实现序列化接口。
所以提示这个很大原因在于传递的参数没有实现序列化,但是一般都提示参数,为什么提示service 没有实现序列化。
以下是我使用test方法时的异常信息。

com.alibaba.dubbo.rpc.RpcException: Failed to invoke the method updateObuStatus in the service com.etc.service.car.RpcEtcCarInfoService. Tried 3 times of the providers [168.1.1.68:20888] (1/1) from the registry 168.1.1.26:2181 on the consumer 192.168.191.1 using the dubbo version 2.6.2. Last error is: Failed to invoke remote method: updateObuStatus, provider: dubbo://168.1.1.68:20888/com.etc.service.car.RpcEtcCarInfoService?anyhost=true&application=etc-highway-card&check=false&default.timeout=600000&dubbo=2.6.2&generic=false&interface=com.etc.service.car.RpcEtcCarInfoService&methods=updateCarStatus,queryCustomerInfoByCar,zolCreditQuery,updateObuStatus&pid=61936&register.ip=192.168.191.1&remote.timestamp=1572940684076&revision=2.2.0&side=consumer&timeout=60000&timestamp=1572998190117, cause: Failed to send message Request [id=2, version=2.0.0, twoway=true, event=false, broken=false, data=RpcInvocation [methodName=updateObuStatus, parameterTypes=[class com.etc.dto.UpdateObuStatusRequest], arguments=[UpdateObuStatusRequest(carNum=111, vehicleNo=null, vehicleColor=null, tenantId=null, obuActiveTime=null, obuActiveNo=1111, remark=null)], attachments={path=com.etc.service.car.RpcEtcCarInfoService, interface=com.etc.service.car.RpcEtcCarInfoService, version=0.0.0, timeout=60000}]] to /168.1.1.68:20888, cause: Serialized class com.etc.highway.CreditLogServiceTest must implement java.io.Serializable
 Java field: final com.etc.highway.CreditLogServiceTest com.etc.highway.CreditLogServiceTest$1.this$0

	at com.alibaba.dubbo.rpc.cluster.support.FailoverClusterInvoker.doInvoke(FailoverClusterInvoker.java:102)
	at com.alibaba.dubbo.rpc.cluster.support.AbstractClusterInvoker.invoke(AbstractClusterInvoker.java:238)
	at com.alibaba.dubbo.rpc.cluster.support.wrapper.MockClusterInvoker.invoke(MockClusterInvoker.java:75)
	at com.alibaba.dubbo.rpc.proxy.InvokerInvocationHandler.invoke(InvokerInvocationHandler.java:52)
	at com.alibaba.dubbo.common.bytecode.proxy13.updateObuStatus(proxy13.java)
	at com.etc.highway.CreditLogServiceTest.getOfflineDataList(CreditLogServiceTest.java:41)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73)
	at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)
	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
	at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: com.alibaba.dubbo.remoting.RemotingException: Failed to send message Request [id=2, version=2.0.0, twoway=true, event=false, broken=false, data=RpcInvocation [methodName=updateObuStatus, parameterTypes=[class com.etc.dto.UpdateObuStatusRequest], arguments=[UpdateObuStatusRequest(carNum=111, vehicleNo=null, vehicleColor=null, tenantId=null, obuActiveTime=null, obuActiveNo=1111, remark=null)], attachments={path=com.etc.service.car.RpcEtcCarInfoService, interface=com.etc.service.car.RpcEtcCarInfoService, version=0.0.0, timeout=60000}]] to /168.1.1.68:20888, cause: Serialized class com.etc.highway.CreditLogServiceTest must implement java.io.Serializable
 Java field: final com.etc.highway.CreditLogServiceTest com.etc.highway.CreditLogServiceTest$1.this$0
	at com.alibaba.dubbo.remoting.transport.netty.NettyChannel.send(NettyChannel.java:110)
	at com.alibaba.dubbo.remoting.transport.AbstractClient.send(AbstractClient.java:265)
	at com.alibaba.dubbo.remoting.transport.AbstractPeer.send(AbstractPeer.java:53)
	at com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeChannel.request(HeaderExchangeChannel.java:115)
	at com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeClient.request(HeaderExchangeClient.java:90)
	at com.alibaba.dubbo.rpc.protocol.dubbo.ReferenceCountExchangeClient.request(ReferenceCountExchangeClient.java:83)
	at com.alibaba.dubbo.rpc.protocol.dubbo.DubboInvoker.doInvoke(DubboInvoker.java:95)
	at com.alibaba.dubbo.rpc.protocol.AbstractInvoker.invoke(AbstractInvoker.java:148)
	at com.alibaba.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java:75)
	at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:72)
	at com.alibaba.dubbo.rpc.protocol.dubbo.filter.FutureFilter.invoke(FutureFilter.java:54)
	at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:72)
	at com.alibaba.dubbo.rpc.filter.ConsumerContextFilter.invoke(ConsumerContextFilter.java:48)
	at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:72)
	at com.alibaba.dubbo.rpc.listener.ListenerInvokerWrapper.invoke(ListenerInvokerWrapper.java:77)
	at com.alibaba.dubbo.rpc.protocol.InvokerWrapper.invoke(InvokerWrapper.java:56)
	at com.alibaba.dubbo.rpc.cluster.support.FailoverClusterInvoker.doInvoke(FailoverClusterInvoker.java:78)
	... 35 more
Caused by: java.lang.RuntimeException: Serialized class com.etc.highway.CreditLogServiceTest must implement java.io.Serializable
 Java field: final com.etc.highway.CreditLogServiceTest com.etc.highway.CreditLogServiceTest$1.this$0
	at com.alibaba.com.caucho.hessian.io.JavaSerializer$FieldSerializer.serialize(JavaSerializer.java:300)
	at com.alibaba.com.caucho.hessian.io.JavaSerializer.writeInstance(JavaSerializer.java:280)
	at com.alibaba.com.caucho.hessian.io.JavaSerializer.writeObject(JavaSerializer.java:247)
	at com.alibaba.com.caucho.hessian.io.Hessian2Output.writeObject(Hessian2Output.java:391)
	at com.alibaba.dubbo.common.serialize.hessian2.Hessian2ObjectOutput.writeObject(Hessian2ObjectOutput.java:88)
	at com.alibaba.dubbo.rpc.protocol.dubbo.DubboCodec.encodeRequestData(DubboCodec.java:176)
	at com.alibaba.dubbo.remoting.exchange.codec.ExchangeCodec.encodeRequest(ExchangeCodec.java:234)
	at com.alibaba.dubbo.remoting.exchange.codec.ExchangeCodec.encode(ExchangeCodec.java:71)
	at com.alibaba.dubbo.rpc.protocol.dubbo.DubboCountCodec.encode(DubboCountCodec.java:38)
	at com.alibaba.dubbo.remoting.transport.netty.NettyCodecAdapter$InternalEncoder.encode(NettyCodecAdapter.java:80)
	at org.jboss.netty.handler.codec.oneone.OneToOneEncoder.handleDownstream(OneToOneEncoder.java:66)
	at com.alibaba.dubbo.remoting.transport.netty.NettyHandler.writeRequested(NettyHandler.java:98)
	at org.jboss.netty.channel.Channels.write(Channels.java:611)
	at org.jboss.netty.channel.Channels.write(Channels.java:578)
	at org.jboss.netty.channel.AbstractChannel.write(AbstractChannel.java:251)
	at com.alibaba.dubbo.remoting.transport.netty.NettyChannel.send(NettyChannel.java:100)
	... 51 more
Caused by: java.lang.IllegalStateException: Serialized class com.etc.highway.CreditLogServiceTest must implement java.io.Serializable
	at com.alibaba.com.caucho.hessian.io.SerializerFactory.getDefaultSerializer(SerializerFactory.java:395)
	at com.alibaba.com.caucho.hessian.io.SerializerFactory.getSerializer(SerializerFactory.java:369)
	at com.alibaba.com.caucho.hessian.io.Hessian2Output.writeObject(Hessian2Output.java:389)
	at com.alibaba.com.caucho.hessian.io.JavaSerializer$FieldSerializer.serialize(JavaSerializer.java:298)
	... 66 more

2.  分析

极大的可能在于service用了rpc中的request对象构建了匿名内部类
所以提示  Java field: final xxx.this$0
JDK8 以后,匿名内部类默认用 final 修饰。
这个 UpdateObuStatusRequest 是本来rpc-api的jar中的需要传参数的对象,错误代码如下,但是在调用的时候,使用了匿名内部类。

    @Autowired
    private RpcEtcCarInfoService rpcEtcCarInfoService;
    @Test
    public void test() throws InterruptedException {
        // 2.通知teacher
        UpdateObuStatusRequest updateObuStatusRequest = new UpdateObuStatusRequest() {
            {
                this.setCarNum("111");
                this.setObuActiveNo("1111");
            }
        };
        ExterResponse exterResponse = rpcEtcCarInfoService.updateObuStatus(updateObuStatusRequest);
        System.out.println(JSON.toJSONString(exterResponse));
    }

跟了下源码,可以看到的是。在使用netty进行 消息发送的时候,对参数进行序列化,用反射获取的是匿名内部类的对应的当前类的对象。刚调用 send 方法的时候,看到的request 对象的参数是对的。

进行序列化的时候。发现这个object是当前测试类的对象。

好吧,下次注意。另外不建议匿名内部类的写法

由于创建的对象用final 修饰后,直接进入了常量池,生存时间不再和调用方法是一样的,容易造成 leak memory(内存泄露)。

发布了115 篇原创文章 · 获赞 58 · 访问量 23万+

猜你喜欢

转载自blog.csdn.net/Angry_Mills/article/details/102988755