protobuf 泛化调用类型校验异常问题
- Dominant language
- Java
- Stars
- 41.6k
- Forks
- 26.4k
- Avg merge
- 15h 13m
- Merged PRs (30d)
- 4
Description
最近在调研泛化调用的功能
构造的请求如下
`reference.setGeneric(GENERIC_SERIALIZATION_PROTOBUF);
GenericService genericService = reference.get();
Object response = genericService.$invoke("getMixResult",
new String[]{"com.xxx.xx.xxxx.xx.entity.MixRequest"},
new Object[]{mixRequest});`
然后会报出如下错误
`cause: org.apache.dubbo.remoting.RemotingException: io.netty.handler.codec.EncoderException: java.lang.IllegalArgumentException: This serialization only supports google protobuf objects, current object class is: [Ljava.lang.String;
io.netty.handler.codec.EncoderException: java.lang.IllegalArgumentException: This serialization only supports google protobuf objects, current object class is: [Ljava.lang.String;
at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:125)
at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:717)
at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:709)
at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:792)
at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:702)
at io.netty.handler.timeout.IdleStateHandler.write(IdleStateHandler.java:304)
at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:717)
at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:709)
at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:792)
at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:702)
at io.netty.channel.ChannelDuplexHandler.write(ChannelDuplexHandler.java:115)
at org.apache.dubbo.remoting.transport.netty4.NettyClientHandler.write(NettyClientHandler.java:88)
at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:717)
at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:764)
at io.netty.channel.AbstractChannelHandlerContext$WriteTask.run(AbstractChannelHandlerContext.java:1071)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.IllegalArgumentException: This serialization only supports google protobuf objects, current object class is: [Ljava.lang.String;
at org.apache.dubbo.common.serialize.protobuf.support.GenericProtobufObjectOutput.writeObject(GenericProtobufObjectOutput.java:109)
at org.apache.dubbo.rpc.protocol.dubbo.DubboCodec.encodeRequestData(DubboCodec.java:207)
at org.apache.dubbo.remoting.exchange.codec.ExchangeCodec.encodeRequest(ExchangeCodec.java:257)
at org.apache.dubbo.remoting.exchange.codec.ExchangeCodec.encode(ExchangeCodec.java:71)
at org.apache.dubbo.rpc.protocol.dubbo.DubboCountCodec.encode(DubboCountCodec.java:47)
at org.apache.dubbo.remoting.transport.netty4.NettyCodecAdapter$InternalEncoder.encode(NettyCodecAdapter.java:69)
at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:107)
... 21 more
at org.apache.dubbo.rpc.cluster.support.FailoverClusterInvoker.doInvoke(FailoverClusterInvoker.java:114)
at org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker.invoke(AbstractClusterInvoker.java:340)
at org.apache.dubbo.rpc.cluster.router.RouterSnapshotFilter.invoke(RouterSnapshotFilter.java:46)
at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:321)
at org.apache.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java:99)
at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:321)
at org.apache.dubbo.rpc.protocol.dubbo.filter.FutureFilter.invoke(FutureFilter.java:51)
at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:321)
at org.apache.dubbo.rpc.cluster.filter.support.ConsumerContextFilter.invoke(ConsumerContextFilter.java:109)
at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:321)
at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CallbackRegistrationInvoker.invoke(FilterChainBuilder.java:193)
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:97)
at org.apache.dubbo.registry.client.migration.MigrationInvoker.invoke(MigrationInvoker.java:280)
at org.apache.dubbo.rpc.proxy.InvocationUtil.invoke(InvocationUtil.java:57)
at org.apache.dubbo.rpc.proxy.InvokerInvocationHandler.invoke(InvokerInvocationHandler.java:73)
at com.heytap.ad.show.mixer.service.IAdShowMixerServiceDubboProxy0.$invoke(IAdShowMixerServiceDubboProxy0.java)
at com.oppo.itest.example.DubboGenericPbTest.main(DubboGenericPbTest.java:100)`
所描述的是在序列化时String[],判断并不是一个pb对象因此序列化失败了
调试之后看到相关代码为
org.apache.dubbo.common.serialize.protobuf.support.GenericProtobufObjectOutput
我在试用dubbo3时将dubbo2的相关逻辑挪移过来的
public void writeObject(Object obj) throws IOException {
/**
* Protobuf does not allow writing of non-protobuf generated messages, including null value.
* Writing of null value from developers should be denied immediately by throwing exception.
*/
if (obj == null) {
throw new IllegalStateException("This serialization only supports google protobuf objects, " +
"please use com.google.protobuf.Empty instead if you want to transmit null values.");
// obj = ProtobufUtils.convertNullToEmpty();
}
if (obj instanceof String) {
obj = StringValue.newBuilder().setValue((String) obj).build();
}
if (!ProtobufUtils.isSupported(obj.getClass())) {
throw new IllegalArgumentException("This serialization only supports google protobuf objects, current object class is: " + obj.getClass().getName());
}
ProtobufUtils.serialize(obj, os);
os.flush();
}
在这个地方只会判断是否为String类型然后将其转换成StringValue类型,但是如同代码块1所示,所传入的参数为String[]类型,因此并不会进行转换,同时在ProtobufUtils.isSupported(obj.getClass())会判断失败从而抛出异常,我尝试性的进行了一些处理但是结果不尽人意,请问该如何修改转化逻辑才能将new String[]{"com.xxx.xx.xxxx.xx.entity.MixRequest"}通过转化呢?
Contributor guide
Assessment
This issue has not been assessed yet.