dubbo2.5.3消费dubbox提供的服务报错

来源:互联网 发布:淘宝怎样套现信用卡 编辑:程序博客网 时间:2024/06/16 16:04

dubbox和dubbo 2.x是兼容的,没有改变dubbo的任何已有的功能和配置方式(除了升级了spring之类的版本),但是实际上确实不能相互兼容相互调用服务。

其实不兼容的原因是因为服务端受理请求时,在DecodeableRpcInvocation这个类出现异常,异常出线的行数106行 :



出现异常的原因报文解析decode异常。这个要了解dubbo协议的报文格式。
in 对象执行read操作,会一个一个偏移读取报文dubbox提供的服务,当执行该行时,认为报文应该是一个整数,但是确是一个String,解析异常。 所以尝试对DecodeableRpcInvocation类进行了兼容处理:

修改的类如下所示:

/* * Copyright 1999-2011 Alibaba Group. * *  Licensed under the Apache License, Version 2.0 (the "License"); *  you may not use this file except in compliance with the License. *  You may obtain a copy of the License at * *       http://www.apache.org/licenses/LICENSE-2.0 * *  Unless required by applicable law or agreed to in writing, software *  distributed under the License is distributed on an "AS IS" BASIS, *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *  See the License for the specific language governing permissions and *  limitations under the License. */package com.alibaba.dubbo.rpc.protocol.dubbo;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.util.HashMap;import java.util.Map;import com.alibaba.dubbo.common.Constants;import com.alibaba.dubbo.common.logger.Logger;import com.alibaba.dubbo.common.logger.LoggerFactory;import com.alibaba.dubbo.common.serialize.Cleanable;import com.alibaba.dubbo.common.serialize.ObjectInput;import com.alibaba.dubbo.common.serialize.OptimizedSerialization;import com.alibaba.dubbo.common.serialize.support.kryo.KryoSerialization;import com.alibaba.dubbo.common.utils.Assert;import com.alibaba.dubbo.common.utils.ReflectUtils;import com.alibaba.dubbo.common.utils.StringUtils;import com.alibaba.dubbo.remoting.Channel;import com.alibaba.dubbo.remoting.Codec;import com.alibaba.dubbo.remoting.Decodeable;import com.alibaba.dubbo.remoting.exchange.Request;import com.alibaba.dubbo.remoting.transport.CodecSupport;import com.alibaba.dubbo.rpc.RpcInvocation;import static com.alibaba.dubbo.rpc.protocol.dubbo.CallbackServiceCodec.decodeInvocationArgument;/** * @author <a href="mailto:gang.lvg@alibaba-inc.com">kimi</a> */public class DecodeableRpcInvocation extends RpcInvocation implements Codec, Decodeable {    private static final Logger log = LoggerFactory.getLogger(DecodeableRpcInvocation.class);    private Channel     channel;    private byte        serializationType;    private InputStream inputStream;    private Request     request;    private volatile boolean hasDecoded;    public DecodeableRpcInvocation(Channel channel, Request request, InputStream is, byte id) {        Assert.notNull(channel, "channel == null");        Assert.notNull(request, "request == null");        Assert.notNull(is, "inputStream == null");        this.channel = channel;        this.request = request;        this.inputStream = is;        this.serializationType = id;    }    public void decode() throws Exception {        if (!hasDecoded && channel != null && inputStream != null) {            try {                decode(channel, inputStream);            } catch (Throwable e) {                if (log.isWarnEnabled()) {                    log.warn("Decode rpc invocation failed: " + e.getMessage(), e);                }                request.setBroken(true);                request.setData(e);            } finally {                hasDecoded = true;            }        }    }    public void encode(Channel channel, OutputStream output, Object message) throws IOException {        throw new UnsupportedOperationException();    }    public Object decode(Channel channel, InputStream input) throws IOException {        ObjectInput in = CodecSupport.getSerialization(channel.getUrl(), serializationType)                .deserialize(channel.getUrl(), input);        try {            setAttachment(Constants.DUBBO_VERSION_KEY, in.readUTF());            setAttachment(Constants.PATH_KEY, in.readUTF());            setAttachment(Constants.VERSION_KEY, in.readUTF());            setMethodName(in.readUTF());            try {                Object[] args;                Class<?>[] pts;                // NOTICE modified by lishen                // 兼容dubbo2.X begin.                String dubboVerson=getAttachment(Constants.DUBBO_VERSION_KEY);                if ("2.5.4".equals(dubboVerson) || "2.5.3".equals(dubboVerson)) {                    String desc=in.readUTF();                    if (desc.length() == 0) {                        pts=DubboCodec.EMPTY_CLASS_ARRAY;                        args=DubboCodec.EMPTY_OBJECT_ARRAY;                    } else {                        pts=ReflectUtils.desc2classArray(desc);                        args=new Object[pts.length];                        for (int i=0; i < args.length; i++) {                            try {                                args[i]=in.readObject(pts[i]);                            } catch (Exception e) {                                if (log.isWarnEnabled()) {                                    log.warn("Decode argument failed: " + e.getMessage(), e);                                }                            }                        }                    }                } // 兼容dubbo2.X  end.                else {                    int argNum=in.readInt();                    if (argNum >= 0) {                        if (argNum == 0) {                            pts=DubboCodec.EMPTY_CLASS_ARRAY;                            args=DubboCodec.EMPTY_OBJECT_ARRAY;                        } else {                            args=new Object[argNum];                            pts=new Class[argNum];                            for (int i=0; i < args.length; i++) {                                try {                                    args[i]=in.readObject();                                    pts[i]=args[i].getClass();                                } catch (Exception e) {                                    if (log.isWarnEnabled()) {                                        log.warn("Decode argument failed: " + e.getMessage(), e);                                    }                                }                            }                        }                    } else {                        String desc=in.readUTF();                        if (desc.length() == 0) {                            pts=DubboCodec.EMPTY_CLASS_ARRAY;                            args=DubboCodec.EMPTY_OBJECT_ARRAY;                        } else {                            pts=ReflectUtils.desc2classArray(desc);                            args=new Object[pts.length];                            for (int i=0; i < args.length; i++) {                                try {                                    args[i]=in.readObject(pts[i]);                                } catch (Exception e) {                                    if (log.isWarnEnabled()) {                                        log.warn("Decode argument failed: " + e.getMessage(), e);                                    }                                }                            }                        }                    }                }                setParameterTypes(pts);                Map<String, String> map=(Map<String, String>) in.readObject(Map.class);                if (map != null && map.size() > 0) {                    Map<String, String> attachment=getAttachments();                    if (attachment == null) {                        attachment=new HashMap<String, String>();                    }                    attachment.putAll(map);                    setAttachments(attachment);                }                //decode argument ,may be callback                for (int i=0; i < args.length; i++) {                    args[i]=decodeInvocationArgument(channel, this, pts, i, args[i]);                }                setArguments(args);            } catch (ClassNotFoundException e) {                throw new IOException(StringUtils.toString("Read invocation data failed.", e));            }        } finally {            // modified by lishen            if (in instanceof Cleanable) {                ((Cleanable) in).cleanup();            }        }        return this;    }}

修改完这块代码打成jar包重新定义dubbo版本为3.8.4,这样的方式可以解决的问题是2,5.3可以消费3.8.4的服务,但是3.8.4不能消费2.5.3的服务,所以作为服务的提供方,应该升到3.8.4,如果仅仅是消费服务而不提供服务,可以用低版本的dubbo
原创粉丝点击