apache / dubbo-hessian-lite Goto Github PK
View Code? Open in Web Editor NEWHessian Lite for Apache Dubbo
License: Apache License 2.0
Hessian Lite for Apache Dubbo
License: Apache License 2.0
@RestController
public class DemoController {
@reference(version = "1.0.0", url = "dubbo://127.0.0.1:12345")
private DemoService demoService;
@GetMapping("/sayHello")
public void sayHello(Pageable pageable) {
System.out.println("controller sayHello");
System.out.println(String.format("pageable: page=%d, size=%d", pageable.getPageNumber(), pageable.getPageSize()));
demoService.sayHello(pageable);
}
}`
@service(version = "1.0.0")
public class DemoServiceImpl implements DemoService {
@OverRide
public void sayHello(Pageable pageable) {
System.out.println(String.format("pageable: page=%d, size=%d", pageable.getPageNumber(), pageable.getPageNumber()));
}
}`
Pls. provide [GitHub address] to reproduce this issue.
We expect in the com.example.dubbo.provider.DemoServiceImpl#sayHello method, the param can be initial correctly, in this case, it should print "page=0, size=20" successfully,which is the default value of an instance of PageRequest class.
On the provider side ,we get an exception indicate that can NOT initial an instance of rg.springframework.data.domain.PageRequest class.
2020-08-11 16:00:14.159 WARN 229668 --- [:12345-thread-2] o.a.d.r.p.dubbo.DecodeableRpcInvocation : [DUBBO] Decode argument failed: 'org.springframework.data.domain.PageRequest' could not be instantiated, dubbo version: 2.7.7, current host: 160.12.11.53
com.alibaba.com.caucho.hessian.io.HessianProtocolException: 'org.springframework.data.domain.PageRequest' could not be instantiated
at com.alibaba.com.caucho.hessian.io.JavaDeserializer.instantiate(JavaDeserializer.java:317) ~[dubbo-2.7.7.jar:2.7.7]
at com.alibaba.com.caucho.hessian.io.JavaDeserializer.readObject(JavaDeserializer.java:202) ~[dubbo-2.7.7.jar:2.7.7]
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObjectInstance(Hessian2Input.java:2848) ~[dubbo-2.7.7.jar:2.7.7]
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2175) ~[dubbo-2.7.7.jar:2.7.7]
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2104) ~[dubbo-2.7.7.jar:2.7.7]
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2148) ~[dubbo-2.7.7.jar:2.7.7]
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2104) ~[dubbo-2.7.7.jar:2.7.7]
at org.apache.dubbo.common.serialize.hessian2.Hessian2ObjectInput.readObject(Hessian2ObjectInput.java:100) ~[dubbo-2.7.7.jar:2.7.7]
at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.decode(DecodeableRpcInvocation.java:143) [dubbo-2.7.7.jar:2.7.7]
at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.decode(DecodeableRpcInvocation.java:80) [dubbo-2.7.7.jar:2.7.7]
at org.apache.dubbo.remoting.transport.DecodeHandler.decode(DecodeHandler.java:57) [dubbo-2.7.7.jar:2.7.7]
at org.apache.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:44) [dubbo-2.7.7.jar:2.7.7]
at org.apache.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:57) [dubbo-2.7.7.jar:2.7.7]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_112]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_112]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_112]
Caused by: java.lang.reflect.InvocationTargetException: null
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_112]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_112]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_112]
at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_112]
at com.alibaba.com.caucho.hessian.io.JavaDeserializer.instantiate(JavaDeserializer.java:313) ~[dubbo-2.7.7.jar:2.7.7]
... 15 common frames omitted
Caused by: java.lang.IllegalArgumentException: Page size must not be less than one!
at org.springframework.data.domain.AbstractPageRequest.<init>(AbstractPageRequest.java:50) ~[spring-data-commons-2.3.2.RELEASE.jar:2.3.2.RELEASE]
at org.springframework.data.domain.PageRequest.<init>(PageRequest.java:43) ~[spring-data-commons-2.3.2.RELEASE.jar:2.3.2.RELEASE]
... 20 common frames omitted
After debugged on this, we founded when deserializing params using hessian (which is the default serialize method using by dubbo protocol), the size field which is int type in PageRequest class was initialled to 0, but the constructor of org.springframework.data.domain.PageRequest can not permit this field less than one.
Why hessian can not call the constructor with values of the params received from the consumer side, instead of with initial values?
The error log is as follows:
java.lang.reflect.InaccessibleObjectException: Unable to make field private byte java.lang.StackTraceElement.format accessible: module java.base does not "opens java.lang" to unnamed module @14514713
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178)
at java.base/java.lang.reflect.Field.setAccessible(Field.java:172)
at com.alibaba.com.caucho.hessian.io.JavaDeserializer.getFieldMap(JavaDeserializer.java:339)
at com.alibaba.com.caucho.hessian.io.JavaDeserializer.<init>(JavaDeserializer.java:79)
at com.alibaba.com.caucho.hessian.io.StackTraceElementDeserializer.<init>(StackTraceElementDeserializer.java:56)
at com.alibaba.com.caucho.hessian.io.SerializerFactory.<clinit>(SerializerFactory.java:192)
at com.alibaba.com.caucho.hessian.io.HessianOutput.init(HessianOutput.java:108)
at com.alibaba.com.caucho.hessian.io.HessianOutput.<init>(HessianOutput.java:89)
at com.alibaba.com.caucho.hessian.io.base.SerializeTestBase.baseHessianSerialize(SerializeTestBase.java:43)
at com.alibaba.com.caucho.hessian.io.Hessian1StringShortTest.serialize_string_short_map_then_deserialize(Hessian1StringShortTest.java:47)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
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.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
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.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:221)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
this class: com.alibaba.com.caucho.hessian.io.CollectionDeserializer.class
CollectionDeserializer.readLengthList.createList()
you can put a length param into this createList method and initialize the collection with length so that the collection will not resize
it will avoid the resize of the collection and save cpu resources
before:
private Collection createList()
throws IOException {
Collection list = null;
if (_type == null)
list = new ArrayList();
else if (!_type.isInterface()) {
try {
list = (Collection) _type.newInstance();
} catch (Exception e) {
}
}
if (list != null) {
} else if (SortedSet.class.isAssignableFrom(_type))
list = new TreeSet();
else if (Set.class.isAssignableFrom(_type))
list = new HashSet();
else if (List.class.isAssignableFrom(_type))
list = new ArrayList();
else if (Collection.class.isAssignableFrom(_type))
list = new ArrayList();
else {
try {
list = (Collection) _type.newInstance();
} catch (Exception e) {
throw new IOExceptionWrapper(e);
}
}
return list;
}
after:
private Collection createList(int length)
throws IOException {
Collection list = null;
if (_type == null)
list = new ArrayList();
else if (!_type.isInterface()) {
try {
list = (Collection) _type.newInstance();
} catch (Exception e) {
}
}
if (list != null) {
} else if (SortedSet.class.isAssignableFrom(_type))
list = new TreeSet(length);
else if (Set.class.isAssignableFrom(_type))
list = new HashSet(length);
else if (List.class.isAssignableFrom(_type))
list = new ArrayList(length);
else if (Collection.class.isAssignableFrom(_type))
list = new ArrayList(length);
else {
try {
list = (Collection) _type.newInstance();
} catch (Exception e) {
throw new IOExceptionWrapper(e);
}
}
return list;
}
使用dubbo协议,暴露的接口参数中含有EnumSet,消费端调用传入值后(EnumSet.of(e)),服务端收到的值为null,详细的异常信息:
java.lang.UnsupportedOperationException: com.alibaba.com.caucho.hessian.io.CollectionDeserializer@1360218
at com.alibaba.com.caucho.hessian.io.AbstractDeserializer.readObject(AbstractDeserializer.java:103)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObjectInstance(Hessian2Input.java:2067)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:1592)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:1576)
at com.alibaba.dubbo.common.serialize.support.hessian.Hessian2ObjectInput.readObject(Hessian2ObjectInput.java:94)
at com.alibaba.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.decode(DecodeableRpcInvocation.java:109)
at com.alibaba.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.decode(DecodeableRpcInvocation.java:71)
at com.alibaba.dubbo.rpc.protocol.dubbo.DubboCodec.decodeBody(DubboCodec.java:137)
at com.alibaba.dubbo.remoting.exchange.codec.ExchangeCodec.decode(ExchangeCodec.java:128)
at com.alibaba.dubbo.remoting.exchange.codec.ExchangeCodec.decode(ExchangeCodec.java:87)
at com.alibaba.dubbo.rpc.protocol.dubbo.DubboCountCodec.decode(DubboCountCodec.java:49)
at com.alibaba.dubbo.remoting.transport.netty.NettyCodecAdapter$InternalDecoder.messageReceived(NettyCodecAdapter.java:135)
at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:80)
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:559)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:274)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:261)
at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:349)
at org.jboss.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:280)
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:200)
at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108)
at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:44)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Version 3.2.5-SNAPSHOT
@Test
public void serialize_short_set_then_deserialize() throws Exception {
Hessian2StringShortType stringShort = new Hessian2StringShortType();
Set<Short> shortSet = new HashSet<Short>();
shortSet.add((short) 0);
shortSet.add((short) 60);
stringShort.shortSet = shortSet;
Hessian2StringShortType deserialize = baseHessian2Serialize(stringShort);
assertTrue(deserialize.shortSet != null);
assertTrue(deserialize.shortSet.size() == 2);
assertTrue(deserialize.shortSet.contains((short) 0));
assertTrue(deserialize.shortSet.contains((short) 60));
}
Assert Failed.
deserialize.shortSet contains (Integer)0 and (Integer) 60
Pls. provide [GitHub address] to reproduce this issue.
https://github.com/lucky-xin/dubbo-samples.git
直接使用Hessian2Output和Hessian2Input进行序列化与反序列也会报错
原因是com.alibaba.com.caucho.hessian.io.CollectionDeserializer的readObject没有实现
com.alibaba.com.caucho.hessian.io.HessianFieldException: org.example.entity.QueryData.sorts: java.util.List cannot be assigned from null
at com.alibaba.com.caucho.hessian.io.JavaDeserializer.logDeserializeError(JavaDeserializer.java:174)
at com.alibaba.com.caucho.hessian.io.JavaDeserializer$ObjectListFieldDeserializer.deserialize(JavaDeserializer.java:534)
at com.alibaba.com.caucho.hessian.io.JavaDeserializer.readObject(JavaDeserializer.java:277)
at com.alibaba.com.caucho.hessian.io.JavaDeserializer.readObject(JavaDeserializer.java:204)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObjectInstance(Hessian2Input.java:2848)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2175)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2104)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2148)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2104)
at org.example.consumer.Demo.test(Demo.java:39)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:214)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: java.lang.UnsupportedOperationException: CollectionDeserializer[interface java.util.List]
at com.alibaba.com.caucho.hessian.io.AbstractDeserializer.readObject(AbstractDeserializer.java:127)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObjectInstance(Hessian2Input.java:2848)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2175)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2104)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2148)
at com.alibaba.com.caucho.hessian.io.JavaDeserializer$ObjectListFieldDeserializer.deserialize(JavaDeserializer.java:528)
... 77 more
Process finished with exit code 255
If there is an exception, please attach the exception trace:
org.apache.dubbo.rpc.RpcException: Failed to invoke the method query in the service org.example.svc.MongoDataSvc. Tried 3 times of the providers [127.0.0.1:20896] (1/1) from the registry 127.0.0.1:20896 on the consumer 192.168.31.178 using the dubbo version 3.0.4. Last error is: Failed to invoke remote method: query, provider: dubbo://127.0.0.1:20896/org.example.svc.MongoDataSvc?application=consumer&application.version=1.0.0&background=false&interface=org.example.svc.MongoDataSvc&metadata-type=local&pid=3368&qos.enable=false®ister.ip=192.168.31.178&revision=1.0.0&side=consumer&sticky=false&timeout=100000&version=1.0.0, cause: org.apache.dubbo.remoting.RemotingException: Fail to decode request due to: com.alibaba.com.caucho.hessian.io.HessianProtocolException: expected map/object at java.lang.Integer (1)
com.alibaba.com.caucho.hessian.io.HessianProtocolException: expected map/object at java.lang.Integer (1)
at com.alibaba.com.caucho.hessian.io.AbstractDeserializer.error(AbstractDeserializer.java:131)
at com.alibaba.com.caucho.hessian.io.AbstractMapDeserializer.readObject(AbstractMapDeserializer.java:70)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2297)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2104)
at org.apache.dubbo.common.serialize.hessian2.Hessian2ObjectInput.readObject(Hessian2ObjectInput.java:99)
at org.apache.dubbo.common.serialize.ObjectInput.readAttachments(ObjectInput.java:87)
at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.decode(DecodeableRpcInvocation.java:224)
at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.decode(DecodeableRpcInvocation.java:93)
at org.apache.dubbo.remoting.transport.DecodeHandler.decode(DecodeHandler.java:57)
at org.apache.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:44)
at org.apache.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:57)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at org.apache.dubbo.common.threadlocal.InternalRunnable.run(InternalRunnable.java:41)
at java.base/java.lang.Thread.run(Thread.java:829)
at org.apache.dubbo.rpc.cluster.support.FailoverClusterInvoker.doInvoke(FailoverClusterInvoker.java:110)
at org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker.invoke(AbstractClusterInvoker.java:268)
at org.apache.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java:89)
at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$FilterChainNode.invoke(FilterChainBuilder.java:84)
at org.apache.dubbo.rpc.protocol.dubbo.filter.FutureFilter.invoke(FutureFilter.java:51)
at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$FilterChainNode.invoke(FilterChainBuilder.java:84)
at org.apache.dubbo.rpc.cluster.filter.support.ConsumerContextFilter.invoke(ConsumerContextFilter.java:108)
at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$FilterChainNode.invoke(FilterChainBuilder.java:84)
at org.apache.dubbo.rpc.cluster.support.wrapper.AbstractCluster$ClusterFilterInvoker.invoke(AbstractCluster.java:92)
at org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterInvoker.invoke(MockClusterInvoker.java:94)
at org.apache.dubbo.rpc.proxy.InvokerInvocationHandler.invoke(InvokerInvocationHandler.java:92)
at org.apache.dubbo.common.bytecode.proxy0.query(proxy0.java)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
at com.sun.proxy.$Proxy68.query(Unknown Source)
at org.example.consumer.svc.impl.BizSvcImpl.query(BizSvcImpl.java:26)
at org.example.consumer.ConsumerApplicationTest.test(ConsumerApplicationTest.java:34)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:214)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: java.util.concurrent.ExecutionException: org.apache.dubbo.remoting.RemotingException: Fail to decode request due to: com.alibaba.com.caucho.hessian.io.HessianProtocolException: expected map/object at java.lang.Integer (1)
com.alibaba.com.caucho.hessian.io.HessianProtocolException: expected map/object at java.lang.Integer (1)
at com.alibaba.com.caucho.hessian.io.AbstractDeserializer.error(AbstractDeserializer.java:131)
at com.alibaba.com.caucho.hessian.io.AbstractMapDeserializer.readObject(AbstractMapDeserializer.java:70)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2297)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2104)
at org.apache.dubbo.common.serialize.hessian2.Hessian2ObjectInput.readObject(Hessian2ObjectInput.java:99)
at org.apache.dubbo.common.serialize.ObjectInput.readAttachments(ObjectInput.java:87)
at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.decode(DecodeableRpcInvocation.java:224)
at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.decode(DecodeableRpcInvocation.java:93)
at org.apache.dubbo.remoting.transport.DecodeHandler.decode(DecodeHandler.java:57)
at org.apache.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:44)
at org.apache.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:57)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at org.apache.dubbo.common.threadlocal.InternalRunnable.run(InternalRunnable.java:41)
at java.base/java.lang.Thread.run(Thread.java:829)
at java.base/java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:395)
at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2022)
at org.apache.dubbo.rpc.AsyncRpcResult.get(AsyncRpcResult.java:181)
at org.apache.dubbo.rpc.protocol.AbstractInvoker.waitForResultIfSync(AbstractInvoker.java:256)
at org.apache.dubbo.rpc.protocol.AbstractInvoker.invoke(AbstractInvoker.java:179)
at org.apache.dubbo.rpc.listener.ListenerInvokerWrapper.invoke(ListenerInvokerWrapper.java:78)
at org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker.invokeWithContext(AbstractClusterInvoker.java:300)
at org.apache.dubbo.rpc.cluster.support.FailoverClusterInvoker.doInvoke(FailoverClusterInvoker.java:79)
... 89 more
Caused by: org.apache.dubbo.remoting.RemotingException: Fail to decode request due to: com.alibaba.com.caucho.hessian.io.HessianProtocolException: expected map/object at java.lang.Integer (1)
com.alibaba.com.caucho.hessian.io.HessianProtocolException: expected map/object at java.lang.Integer (1)
at com.alibaba.com.caucho.hessian.io.AbstractDeserializer.error(AbstractDeserializer.java:131)
at com.alibaba.com.caucho.hessian.io.AbstractMapDeserializer.readObject(AbstractMapDeserializer.java:70)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2297)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2104)
at org.apache.dubbo.common.serialize.hessian2.Hessian2ObjectInput.readObject(Hessian2ObjectInput.java:99)
at org.apache.dubbo.common.serialize.ObjectInput.readAttachments(ObjectInput.java:87)
at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.decode(DecodeableRpcInvocation.java:224)
at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.decode(DecodeableRpcInvocation.java:93)
at org.apache.dubbo.remoting.transport.DecodeHandler.decode(DecodeHandler.java:57)
at org.apache.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:44)
at org.apache.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:57)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at org.apache.dubbo.common.threadlocal.InternalRunnable.run(InternalRunnable.java:41)
at java.base/java.lang.Thread.run(Thread.java:829)
at org.apache.dubbo.remoting.exchange.support.DefaultFuture.doReceived(DefaultFuture.java:214)
at org.apache.dubbo.remoting.exchange.support.DefaultFuture.received(DefaultFuture.java:176)
at org.apache.dubbo.remoting.exchange.support.DefaultFuture.received(DefaultFuture.java:164)
at org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.handleResponse(HeaderExchangeHandler.java:60)
at org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.received(HeaderExchangeHandler.java:181)
at org.apache.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:51)
at org.apache.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:57)
at org.apache.dubbo.common.threadpool.ThreadlessExecutor$RunnableWrapper.run(ThreadlessExecutor.java:196)
at org.apache.dubbo.common.threadpool.ThreadlessExecutor.waitAndDrain(ThreadlessExecutor.java:99)
at org.apache.dubbo.rpc.AsyncRpcResult.get(AsyncRpcResult.java:179)
... 94 more
一般会出现两种情况的异常信息:
com.alibaba.com.caucho.hessian.io.HessianFieldException: xxxxx.XXXDTO.xxxField: xxxxx.CorrectType cannot be assigned from null
Caused by: java.lang.IndexOutOfBoundsException: Index: 16, Size: 15
com.alibaba.com.caucho.hessian.io.HessianFieldException: xxxxx.XXXDTO.xxxField: xxxxx.WrongType cannot be assigned to 'xxxxx.CorrectType'
BadExampleDTO:
package my.hessian.dto;
import java.io.Serializable;
import java.util.UUID;
public class BadExampleDTO implements Serializable {
private Long id;
private UUID sign;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public UUID getSign() {
return sign;
}
public void setSign(UUID sign) {
this.sign = sign;
}
@Override
public String toString() {
return "ExampleDTO{" +
"id=" + id +
", sign=" + sign +
'}';
}
}
MyHessianTest:
package my.hessian;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import com.alibaba.com.caucho.hessian.io.Hessian2Input;
import com.alibaba.com.caucho.hessian.io.Hessian2Output;
import my.hessian.dto.BadExampleDTO;
public class MyHessianTest {
public static void main(String[] args) throws Exception {
List<BadExampleDTO> data = createBadData();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
Hessian2Output output = new Hessian2Output(bos);
output.writeObject(data);
output.flush();
System.out.println(Arrays.toString(bos.toByteArray()));
Hessian2Input input = new Hessian2Input(new ByteArrayInputStream(bos.toByteArray()));
Object o = input.readObject();
System.out.println(o);
}
private static List<BadExampleDTO> createBadData() {
UUID uuid = UUID.randomUUID();
BadExampleDTO badExampleDTO = new BadExampleDTO();
badExampleDTO.setId(1L);
badExampleDTO.setSign(uuid);
BadExampleDTO badExampleDTO2 = new BadExampleDTO();
badExampleDTO2.setId(2L);
badExampleDTO2.setSign(uuid);
return Arrays.asList(badExampleDTO, badExampleDTO2);
}
}
(该代码可复现出上述的第一种报错情况)
在经过调试分析后发现 UUID 类型的属性在序列化和反序列化时分别使用了 StringValueSerializer 和 UUIDDeserializer, 而 StringValueSerializer 在序列化时会尝试通过 _refs 缓存写出 value, 但是 UUIDDeserializer 在反序列化时并不会将反序列化的结果加入到 _refs 缓存中, 导致了在序列化和反序列化时 _refs 的内容不同, 从而出现访问 _refs 索引越界, 或者读取了一个错误的 ref。
I am writting unit tests for IdentityIntMap
and I test for null
key
@Test
public void testIdentityIntMap_null_key() {
IdentityIntMap identityIntMap = new IdentityIntMap();
for (int i = 0; i < 1000; i++) {
identityIntMap.put(null, i);
}
identityIntMap.remove(null);
}
I just put a key null
for 1000 times
the size() of identityIntMap
is 1000 , I am not sure whether I designed for this .
and what's more ,
if I remove key null
it.s return IdentityIntMap.NULL
but the size of identityIntMap still 1000
the source code about the issue is
public int put(Object key, int value) {
int mask = _mask;
int hash = key.hashCode() % mask & mask;
Object[] keys = _keys;
while (true) {
Object testKey = keys[hash];
if (testKey == null || testKey == DELETED) {
keys[hash] = key;
_values[hash] = value;
_size++;
if (keys.length <= 4 * _size)
resize(4 * keys.length);
return NULL;
} else if (key != testKey && !key.equals(testKey)) {
....
}
}
public int remove(Object key) {
int mask = _mask;
int hash = key.hashCode() % mask & mask;
while (true) {
Object mapKey = _keys[hash];
if (mapKey == null)
return NULL;
else if (mapKey == key) {
...
}
hash = (hash + 1) % mask;
}
}
it's a bug ?
private Person getPerson() {
Person person = new Person();
person.setId(123L);
person.setName("好汉");
List<Person> friends = new ArrayList<>(10000);
for (int i = 0; i < 10000; i++) {
Person friend = new Person();
friend.setId(Long.valueOf(i));
friend.setName(String.valueOf("name" + i));
friends.add(friend);
}
person.setFriends(friends);
return person;
}
public static byte[] serializeWithHessianLite(Object object) {
try {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(1 << 10);
com.alibaba.com.caucho.hessian.io.Hessian2Output hessian2Output = new com.alibaba.com.caucho.hessian.io.Hessian2Output(byteArrayOutputStream);
hessian2Output.startMessage();
hessian2Output.writeObject(object);
hessian2Output.completeMessage();
hessian2Output.close();
return byteArrayOutputStream.toByteArray();
} catch (IOException e) {
throw new OperationException("serialize with hessian2 fail: " + e.getMessage());
}
}
public static Object deserializeWithHessianLite(byte[] bytes) {
try {
com.alibaba.com.caucho.hessian.io.Hessian2Input hessian2Input = new com.alibaba.com.caucho.hessian.io.Hessian2Input(new ByteArrayInputStream(bytes));
hessian2Input.startMessage();
Object o = hessian2Input.readObject();
hessian2Input.completeMessage();
hessian2Input.close();
return o;
} catch (IOException e) {
throw new OperationException("deserialize with hessian2 fail: " + e.getMessage());
}
}
然后对getPerson()返回的数据进行10000次序列化和反序列化:
private void hessian2PerformanceTest(Person person) {
//预热
for (int i = 0; i < 10; i++) {
byte[] bytes3 = SerializeTestUtil.serializeWithHessianLite(person);
Object o = SerializeTestUtil.deserializeWithHessianLite(bytes3);
if (i == 0) {
logger.warn("hessian2 序列化后长度={} 反序列化再序列化后长度={}", bytes3.length, SerializeTestUtil.serializeWithHessianLite(o).length);
}
}
long start = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
byte[] bytes = SerializeTestUtil.serializeWithHessianLite(person);
Object o = SerializeTestUtil.deserializeWithHessianLite(bytes);
}
logger.warn("hessian2 序列化、反序列化10000次耗时:{}", System.currentTimeMillis() - start);
}
2019-03-21 19:25:15,652 WARN [main]
c.y.o.s.SerializeBenchmarkTest2.hessian2PerformanceTest(116) - hessian2 序列化后长度=146917 反序列化再序列化后长度=146917
2019-03-21 19:25:56,922 WARN [main] c.y.o.s.SerializeBenchmarkTest2.hessian2PerformanceTest(125) - hessian2 序列化、反序列化10000次耗时:41066
2019-03-21 19:25:57,010 WARN [main] c.y.o.s.SerializeBenchmarkTest2.kryoPerformanceTestWithThreadLocal(134) - kryo(pooling+compatible) 序列化后长度=130718, 反序列化再序列化后长度=130718
2019-03-21 19:26:16,020 WARN [main] c.y.o.s.SerializeBenchmarkTest2.kryoPerformanceTestWithThreadLocal(143) - kryo序列化、反序列化(pooling+compatible)10000次耗时:18958
结果hessian-lite需要40多秒,我也用了kryo做对比,只要18秒,kryo通过ThreadLocal做了缓存。
是我hessian-lite写的不对吗?还有其他提高性能的方法不?
我在dubbo项目上看到了一个issue。我跟踪了一下代码发现是你们这个hessian工程导致的。我在Hessian 4.0.38上没有重新该问题。经过debug,我发现是因为你们的代码缺少了UnsafeDeserializer.class相关类导致的,我在sofa上看到他们已经把hessian协议升级到了高版本。你们这边有升级的计划吗?https://github.com/alipay/sofa-hessian
我们使用dubbo的时候,返回的结果对象是这样的
class Result {
int code;//错误码
String message;//错误消息
T module ;//保存数据
}
但是调用时报反序列失败,报错如下:
Exception in thread "main" com.alibaba.com.caucho.hessian.io.HessianFieldException: AVX$Result.data: com.alibaba.com.caucho.hessian.io.ObjectDeserializer: unexpected object java.lang.String (2) at com.alibaba.com.caucho.hessian.io.JavaDeserializer.logDeserializeError(JavaDeserializer.java:163) at com.alibaba.com.caucho.hessian.io.JavaDeserializer$ObjectFieldDeserializer.deserialize(JavaDeserializer.java:394) at com.alibaba.com.caucho.hessian.io.JavaDeserializer.readObject(JavaDeserializer.java:269) at com.alibaba.com.caucho.hessian.io.JavaDeserializer.readObject(JavaDeserializer.java:196) at com.alibaba.com.caucho.hessian.io.SerializerFactory.readObject(SerializerFactory.java:527) at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObjectInstance(Hessian2Input.java:2743) at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2683) at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2657) at AVX.deserialize(AVX.java:37) at AVX.main(AVX.java:18) Caused by: com.alibaba.com.caucho.hessian.io.HessianProtocolException: com.alibaba.com.caucho.hessian.io.ObjectDeserializer: unexpected object java.lang.String (2) at com.alibaba.com.caucho.hessian.io.AbstractDeserializer.error(AbstractDeserializer.java:101) at com.alibaba.com.caucho.hessian.io.AbstractDeserializer.readMap(AbstractDeserializer.java:90) at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2066) at com.alibaba.com.caucho.hessian.io.JavaDeserializer$ObjectFieldDeserializer.deserialize(JavaDeserializer.java:390) ... 8 more
代码如下:
`
import com.alibaba.com.caucho.hessian.io.Hessian2Input;
import com.alibaba.com.caucho.hessian.io.Hessian2Output;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
public class AVX {
public static void main(String[] args) throws IOException, ClassNotFoundException {
HashMap<String, String> map = new HashMap<>();
map.put("2", "2");
Result<HashMap<String, String>> test = new Result(map);
byte[] bytes = serialize(test);
Result<HashMap<String, String>> mm = (Result<HashMap<String, String>>) deserialize(bytes);
System.out.println(mm);
}
public static byte[] serialize(Object obj) throws IOException {
if (obj == null) throw new NullPointerException();
ByteArrayOutputStream os = new ByteArrayOutputStream();
Hessian2Output ho = new Hessian2Output(os);
ho.writeObject(obj);
ho.flushBuffer();
return os.toByteArray();
}
public static Object deserialize(byte[] by) throws IOException {
if (by == null) throw new NullPointerException();
ByteArrayInputStream is = new ByteArrayInputStream(by);
Hessian2Input hi = new Hessian2Input(is);
return hi.readObject();
}
static class Result<T extends Serializable> implements Serializable {
public Result(T data) {
this.data = data;
}
private T data;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
@Override
public String toString() {
return "Result{" +
"data=" + data +
'}';
}
}
}`
经过测试,如果
static class Result<T extends Serializable> implements Serializable {
改为
static class Result<T> implements Serializable {
则能正常反序列化出来。
求大神帮助 看看
Apache Dubbo默认使用Hessian2作为序列化/反序列化协议。
当使用Hessian2反序列化HashMap对象时,一些存储在HashMap中的函数将被执行。
攻击者可通过构造特定的序列实现任意远程命令执行。
受影响版本为Dubbo 2.7.0至2.7.7;Dubbo 2.6.0至2.6.8;Dubbo 2.5.x。
问下2.7.8版本中有没有修复此漏洞了?
Master branch is not the latest by comparing with com.alibaba:hessian-lite:3.2.6. We are going to add those code back into master, otherwise it will be lost in the furthure release.
rpc返回结果用Stream.collect(Collectors.toList())可以正常返回,用Stream.toList()返回会报错
Caused by: java.lang.UnsupportedOperationException: CollectionDeserializer[interface java.util.List]
at com.alibaba.com.caucho.hessian.io.AbstractDeserializer.readObject(AbstractDeserializer.java:127)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObjectInstance(Hessian2Input.java:2848)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2175)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2104)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2148)
at com.alibaba.com.caucho.hessian.io.JavaDeserializer$ObjectListFieldDeserializer.deserialize(JavaDeserializer.java:528)
java.lang.reflect.InaccessibleObjectException: Unable to make field private byte java.lang.StackTraceElement.format accessible: module java.base does not "opens java.lang" to unnamed module @4563e9ab
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178)
at java.base/java.lang.reflect.Field.setAccessible(Field.java:172)
at com.alibaba.com.caucho.hessian.io.JavaDeserializer.getFieldMap(JavaDeserializer.java:340)
at com.alibaba.com.caucho.hessian.io.JavaDeserializer.<init>(JavaDeserializer.java:80)
at com.alibaba.com.caucho.hessian.io.StackTraceElementDeserializer.<init>(StackTraceElementDeserializer.java:56)
at com.alibaba.com.caucho.hessian.io.SerializerFactory.<clinit>(SerializerFactory.java:189)
at org.apache.dubbo.common.serialize.hessian2.Hessian2FactoryManager.createDefaultSerializerFactory(Hessian2FactoryManager.java:91)
at org.apache.dubbo.common.serialize.hessian2.Hessian2FactoryManager.createSerializerFactory(Hessian2FactoryManager.java:87)
at org.apache.dubbo.common.serialize.hessian2.Hessian2FactoryManager.getSerializerFactory(Hessian2FactoryManager.java:70)
at org.apache.dubbo.common.serialize.hessian2.Hessian2ObjectInput.<init>(Hessian2ObjectInput.java:46)
at org.apache.dubbo.common.serialize.hessian2.Hessian2Serialization.deserialize(Hessian2Serialization.java:66)
I have upgraded the latest version. How to verify whether the cve-2022-39198 deserialization vulnerability still exists
public class User implements java.io.Serializable {
private Map<Long, Long> map;
public Map<Long, Long> getMap() {
return map;
}
public void setMap(Map<Long, Long> map) {
this.map = map;
}
}
序列化之前:
User user = new User();
Map<Long, Long> map = new HashMap<>();
map.put(null, 1L);
user.setMap(map);
String hello = demoService.sayHello(user);
序列化之后,map里面的key变成0
does hessian-lite supoort deserilize cglib object ?
Dear
We are using Hessian-lite via Dubbo for our public APIs.
One of our APIs has a method to transfer data with InputStream as the input param:
Response uploadFile(InputStream stream);
When invoking this method remotely, we receive this exception:
com.alibaba.com.caucho.hessian.io.HessianProtocolException: expected binary at 0x41 [B ([B@3773f20e)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.error(Hessian2Input.java:3546)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.expect(Hessian2Input.java:3520)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readInputStream(Hessian2Input.java:3384)
at com.alibaba.com.caucho.hessian.io.InputStreamDeserializer.readObject(InputStreamDeserializer.java:63)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2267)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2074)
at org.apache.dubbo.common.serialize.hessian2.Hessian2ObjectInput.readObject(Hessian2ObjectInput.java:92)
at org.apache.dubbo.common.serialize.hessian2.Hessian2ObjectInput.readObject(Hessian2ObjectInput.java:97)
at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcResult.handleValue(DecodeableRpcResult.java:134)
at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcResult.decode(DecodeableRpcResult.java:92)
at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcResult.decode(DecodeableRpcResult.java:112)
at org.apache.dubbo.rpc.protocol.dubbo.DubboCodec.decodeBody(DubboCodec.java:92)
at org.apache.dubbo.remoting.exchange.codec.ExchangeCodec.decode(ExchangeCodec.java:122)
at org.apache.dubbo.remoting.exchange.codec.ExchangeCodec.decode(ExchangeCodec.java:82)
at org.apache.dubbo.rpc.protocol.dubbo.DubboCountCodec.decode(DubboCountCodec.java:48)
at org.apache.dubbo.remoting.transport.netty4.NettyCodecAdapter$InternalDecoder.decode(NettyCodecAdapter.java:90)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:647)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:582)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:499)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:461)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:748)
The version of Hessian-lite as used: 3.2.5
Dubbo version: 2.7.3
Could you please take a look?!!
Best regards
TotalForgot
com.alibaba.com.caucho.hessian.io.HessianInput.readObject();
if (List.class != reader.getType() && List.class.isAssignableFrom(reader.getType()))
return reader.readList(this, length, valueType ? expectedTypes.get(0) : null);
第一个条件:List.class != reader.getType() 读取的类型不能是List
第二个条件:List.class.isAssignableFrom(reader.getType())) 判断接口类型,这里明显少了一个 感叹号。
应该加一个感叹号
!List.class.isAssignableFrom(reader.getType()))
否则永远都是list读取
case 'V': {
String type = readType();
如果type为空是否要默认list,否则读取的是map序列化
1.dubbo线程数设置为250
2.偶尔序列化大对象,约18M
3.dump文件发现单个dubbo线程占用heap空间过大,导致频繁full gc,且full gc后内存回收很少。
3.Hessian2Input对象被ThreadLoacal复用,无法回收。成员变量_sbuf重置方法为_sbuf.setLength(0),StringBuilder底层char数组只会重置指针,不会清空数据,如果序列化过大对象,char数组里面会保留很多无效数据,建议Hessian2Input#reset时调用_sbuf.trimToSize方法清理。
for type List<Integer[]>
, the decoded type will be List<List>
, which will cause jackson can't serialize the object, and get the error java.util.ArrayList cannot be cast to [Ljava.lang.Object;
the following code will regenerate the error:
import com.alibaba.com.caucho.hessian.io.HessianInput;
import com.alibaba.com.caucho.hessian.io.HessianOutput;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) throws IOException {
DemoData data = new DemoData();
List<Integer[]> list = new ArrayList<>();
list.add(new Integer[]{1, 2, 3});
list.add(new Integer[]{4, 5, 6});
data.setList(list);
data.setInts(new Integer[]{7, 8, 9});
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(data);
System.out.println(json);
ByteArrayOutputStream out = new ByteArrayOutputStream();
HessianOutput output = new HessianOutput(out);
output.writeObject(data);
ByteArrayInputStream is = new ByteArrayInputStream(out.toByteArray());
HessianInput input = new HessianInput(is);
Object o = input.readObject();
System.out.println(o);
json = objectMapper.writeValueAsString(o);
System.out.println(json);
}
}
class DemoData implements Serializable {
Integer[] ints;
List<Integer[]> list;
public Integer[] getInts() {
return ints;
}
public void setInts(Integer[] ints) {
this.ints = ints;
}
public List<Integer[]> getList() {
return list;
}
public void setList(List<Integer[]> list) {
this.list = list;
}
}
We are going to support protobuf serialzation direct into hessian InputStream & OutputStream.
Dubbo PR: apache/dubbo#5781
But, Hessian2Input cannot analyze 0x41 for large request. Right now, we are going to fullfill that comparing with com.caucho:hessian version.
Caused by: com.alibaba.com.caucho.hessian.io.HessianProtocolException: expected binary at 0x41 [B ([B@783ce658)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.error(Hessian2Input.java:3546) ~[dubbo-2.7.3-ctrip.8.jar:2.7.3-ctrip.8]
at com.alibaba.com.caucho.hessian.io.Hessian2Input.expect(Hessian2Input.java:3520) ~[dubbo-2.7.3-ctrip.8.jar:2.7.3-ctrip.8]
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readInputStream(Hessian2Input.java:3384) ~[dubbo-2.7.3-ctrip.8.jar:2.7.3-ctrip.8]
at org.apache.dubbo.common.serialize.hessian2.Hessian2ObjectInput.readInputStream(Hessian2ObjectInput.java:101) ~[dubbo-2.7.3-ctrip.8.jar:2.7.3-ctrip.8]
JDK: 17
hessian-lite version: 3.2.12
序列化代码如下:
@Override
public byte[] serialize(Object obj) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
Hessian2Output hessian2Output = new Hessian2Output(out);
try {
hessian2Output.writeObject(obj);
hessian2Output.flush();
} catch (Exception e) {
e.printStackTrace();
}
return out.toByteArray();
}
报错:
java.lang.reflect.InaccessibleObjectException: Unable to make field final int java.math.BigInteger.signum accessible: module java.base does not "opens java.math" to unnamed module @2f410acfjava.lang.reflect.InaccessibleObjectException: Unable to make field final int java.math.BigInteger.signum accessible: module java.base does not "opens java.math" to unnamed module @2f410acf
Pls. provide [GitHub address] to reproduce this issue.
期望消费者与提供者之间传递ObjectId时,序列化以及反序列化之后,ObjectId值不变
If there is an exception, please attach the exception trace:
Just put your stack trace here!
When input value include 4 byte unicode char, eg. emoji chars, should transfer to utf-8, but printString() function all not do that.
https://github.com/dubbo/hessian-lite/blob/5a74492fb347b358bbc19350b695d082171ad3e9/src/main/java/com/alibaba/com/caucho/hessian/io/Hessian2Output.java#L891
Here should use utf-8 bytes array length, not chars length. Emoji chars's length is 2 in Java, but other language eg. PHP is 4.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.