Skip to content

NoSuchMethodError are thrown when add custom Filter using dubbo2.6.5 and JDK1.6 and upgrade to dubbo2.7.0 #3570

@cdfive

Description

@cdfive

Environment

  • Dubbo version: 2.6.0 2.7.0
  • Operating System version: win7 win10
  • Java version: JDK1.6 JDK1.8

Steps to reproduce this issue

  1. Add a module using dubbo 2.6.0, JDK1.6
    add a custorm XxxFilter and override the invoke method:
@Activate(group = "provider")
public class SentinelDubboProviderFilter extends AbstractDubboFilter implements Filter {
    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        ...
        Result invoke(Invoker<?> invoker, Invocation invocation);
        ...
    }
}

then add a file named com.alibaba.dubbo.rpc.Filter in resources/META-INF.dubbo:
xxx.filter=com.xxx.XxxFilter

  1. Add a new project using dubbo 2.6.0, JDK1.6
    add the module dependency of the step1, to use XxxFilter,
    start the dubbo application as provider,
    and using another project as consumer to invoke provider's method.
    the XxxFilter will be effected, It's OK.
    when upgrade the new project version to dubbo 2.7.0,JDK1.8
    the XxxFilter will be also entered, but Error are thrown:
java.lang.NoSuchMethodError: com.alibaba.dubbo.rpc.Invoker.invoke(Lcom/alibaba/dubbo/rpc/Invocation;)Lcom/alibaba/dubbo/rpc/Result;
at com.xxx.XxxFilter.invoke(SentinelDubboProviderFilter.java:68)
	at com.alibaba.dubbo.rpc.Filter.invoke(Filter.java:29)
...

Learned from http://dubbo.apache.org/zh-cn/blog/dubbo-compatible.html

dubbo-compatible module using default interface method of JDK1.8
and proxy pattern for implement the repackage from com.alibaba.dubbo to org.apache.dubbo.

If using dubbo 2.7.0 and JDK1.8 in the module of step1, it's OK, and the XxxFilter need't modify.
But when package with dubbo 2.6.x version, the NoSuchMethodError occured when another project
using the XxxFilter.

Since the module may be a third module using by other projects.
the module is considered to support JDK1.6 or higher, not must at least JDK1.8 as dubbo 2.7.0
and it's also considered to support both dubbo 2.6.x and dubbo 2.7.0.

As the Sentinel Filter in sentinel-dubbo-adapter module met this Error:
alibaba/Sentinel#496
It's wished that no code need to modify in Filter, and support dubbo 2.6.x,2.7.0, JDK1.6,1.7,1.8.

I tried to modify the Invoker interface in com.alibaba.dubbo.rpc package in the dubbo-compatible
module of dubbo 2.7.0,

@Deprecated
public interface Invoker<T> extends org.apache.dubbo.rpc.Invoker<T> {

    @Override
    Result invoke(org.apache.dubbo.rpc.Invocation invocation) throws RpcException;

    Result invoke(Invocation invocation);
    
    default org.apache.dubbo.rpc.Invoker<T> getOriginal() {
        return null;
    }

    class CompatibleInvoker<T> implements Invoker<T> {

        private org.apache.dubbo.rpc.Invoker<T> invoker;

        public CompatibleInvoker(org.apache.dubbo.rpc.Invoker<T> invoker) {
            this.invoker = invoker;
        }

        @Override
        public Class<T> getInterface() {
            return invoker.getInterface();
        }

        @Override
        public Result invoke(org.apache.dubbo.rpc.Invocation invocation) throws RpcException {
            return new Result.CompatibleResult(invoker.invoke(((Invocation) invocation).getOriginal()));
        }

        @Override
        public Result invoke(Invocation invocation) throws RpcException {
            return new Result.CompatibleResult(invoker.invoke(invocation));
        }

        @Override
        public URL getUrl() {
            return invoker.getUrl();
        }

        @Override
        public boolean isAvailable() {
            return invoker.isAvailable();
        }

        @Override
        public void destroy() {
            invoker.destroy();
        }

        @Override
        public org.apache.dubbo.rpc.Invoker<T> getOriginal() {
            return invoker;
        }
    }
}

add Result invoke(Invocation invocation); interface and override it in CompatibleInvoker,
It's OK in step2, both dubbo 2.6.x & JDK1.6 and dubbo 2.7.0 & JDK1.8works.

But this way need modify many code, as the user may call
invoker.getUrl() or RpcContext.getContext().setAttachment method in Filter
NoSuchMethodError will be also thrown.

Could someone please give some suggestions?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions