You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2019/11/03 05:34:32 UTC

[dubbo] branch master updated (cea3de7 -> 02eabd6)

This is an automated email from the ASF dual-hosted git repository.

liujun pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo.git.


    from cea3de7  Refactor, revert ReferenceConfigCache package change
     new 288aa4a  refactor online and offline
     new b797852  fix unit test for online and offline
     new c152c3c  Merge pull request #5 from cvictory/merge-3.x
     new c30a430  ExtensionLoader try to load resource from itself ClassLoader first
     new 88c2386  Merge branch 'merge-3.x' of github.com:chickenlj/incubator-dubbo into merge-3.x
     new fe2b127  ExtensionLoader load META-INF/dubbo/internal/ extension from ExtensionLoader ClassLoader first
     new 128a50a  update comment
     new c18e6c3  to process a scenario when service type is not available and service invocation is not generic either
     new 0ad3577  enhance generic invocation check
     new e826d08  to process a scenario when service type is not available and service invocation is not generic either
     new 1090348  Merge branch 'merge-3.x'
     new 02eabd6  generic codec & bootstrap api

The 12 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../org/apache/dubbo/bootstrap/DubboBootstrap.java |  9 +++
 .../org/apache/dubbo/config/ReferenceConfig.java   |  8 +-
 .../org/apache/dubbo/config/ServiceConfig.java     |  8 +-
 .../dubbo/config/utils/ReferenceConfigCache.java   |  2 +
 .../apache/dubbo/config/spring/ReferenceBean.java  |  5 ++
 .../org/apache/dubbo/common/ServiceDescriptor.java | 94 ++++++++++++++++++++++
 .../src/main/java/org/apache/dubbo/common/URL.java | 16 +---
 .../common/config/OrderedPropertiesProvider.java   |  5 ++
 .../configcenter/DynamicConfigurationFactory.java  |  2 +-
 .../dubbo/common/constants/CommonConstants.java    |  2 +
 .../dubbo/common/extension/ExtensionLoader.java    | 39 +++++----
 .../apache/dubbo/common/utils/ReflectUtils.java    | 10 +++
 .../dubbo/config/service/ReferenceConfig.java      |  5 +-
 .../apache/dubbo/rpc/model/MethodDescriptor.java   |  9 ++-
 .../apache/dubbo/rpc/model/ServiceMetadata.java    | 45 ++---------
 .../store/InMemoryWritableMetadataService.java     |  5 +-
 .../store/RemoteWritableMetadataService.java       |  5 +-
 .../org/apache/dubbo/qos/command/impl/Offline.java | 38 ++++-----
 .../org/apache/dubbo/qos/command/impl/Online.java  | 39 ++++-----
 .../dubbo/qos/command/impl/TestInterface.java      |  9 +++
 .../dubbo/qos/command/impl/TestInterface2.java     |  9 +++
 .../org/apache/dubbo/rpc/ClusterInterceptor.java   | 11 ++-
 .../src/main/java/org/apache/dubbo/rpc/Filter.java | 25 +++---
 .../main/java/org/apache/dubbo/rpc/Invocation.java | 12 +++
 .../java/org/apache/dubbo/rpc/RpcInvocation.java   | 12 +++
 .../apache/dubbo/rpc/filter/GenericImplFilter.java | 39 ++++++---
 .../org/apache/dubbo/rpc/support/RpcUtils.java     | 21 +++++
 .../protocol/dubbo/DecodeableRpcInvocation.java    | 37 +++++----
 .../dubbo/rpc/protocol/dubbo/DubboCodec.java       |  3 +-
 29 files changed, 363 insertions(+), 161 deletions(-)
 create mode 100644 dubbo-common/src/main/java/org/apache/dubbo/common/ServiceDescriptor.java
 create mode 100644 dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/TestInterface.java
 create mode 100644 dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/TestInterface2.java


[dubbo] 07/12: update comment

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo.git

commit 128a50a6a9eddf4626f0cfe9d007bbe9915c3402
Author: hengyunabc <he...@gmail.com>
AuthorDate: Fri Oct 18 17:49:12 2019 +0800

    update comment
---
 .../org/apache/dubbo/common/config/OrderedPropertiesProvider.java    | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/OrderedPropertiesProvider.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/OrderedPropertiesProvider.java
index 28ab275..4068311 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/OrderedPropertiesProvider.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/OrderedPropertiesProvider.java
@@ -21,6 +21,11 @@ import org.apache.dubbo.common.extension.SPI;
 
 import java.util.Properties;
 
+/**
+ * 
+ * The smaller value, the higher priority
+ * 
+ */
 @SPI
 public interface OrderedPropertiesProvider {
     /**


[dubbo] 04/12: fix unit test for online and offline

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo.git

commit b797852fb3a8f3a56da2e66cf6578f99734c91d6
Author: cvictory <sh...@gmail.com>
AuthorDate: Sat Oct 12 14:56:00 2019 +0800

    fix unit test for online and offline
---
 .../org/apache/dubbo/qos/command/impl/LsTest.java  |  2 +-
 .../apache/dubbo/qos/command/impl/OfflineTest.java | 20 +++++++++++++-------
 .../apache/dubbo/qos/command/impl/OnlineTest.java  | 22 +++++++++++++++-------
 .../dubbo/qos/command/impl/TestInterface.java      |  9 +++++++++
 .../dubbo/qos/command/impl/TestInterface2.java     |  9 +++++++++
 5 files changed, 47 insertions(+), 15 deletions(-)

diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/LsTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/LsTest.java
index c82e2d5..b83beb6 100644
--- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/LsTest.java
+++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/LsTest.java
@@ -72,6 +72,6 @@ public class LsTest {
         Ls ls = new Ls();
         String output = ls.execute(mock(CommandContext.class), null);
         assertThat(output, containsString("org.apache.dubbo.FooService|100"));
-        assertThat(output, containsString("org.apache.dubbo.BarService| Y"));
+        assertThat(output, containsString("org.apache.dubbo.BarService"));
     }
 }
diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/OfflineTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/OfflineTest.java
index f498d5a..1352d86 100644
--- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/OfflineTest.java
+++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/OfflineTest.java
@@ -24,6 +24,8 @@ import org.apache.dubbo.registry.support.ProviderInvokerWrapper;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 import org.apache.dubbo.rpc.model.ProviderModel;
+import org.apache.dubbo.rpc.model.ServiceMetadata;
+
 import org.junit.jupiter.api.Test;
 import org.mockito.Mockito;
 
@@ -38,18 +40,21 @@ public class OfflineTest {
     @Test
     public void testExecute() throws Exception {
         ProviderModel providerModel = mock(ProviderModel.class);
-        when(providerModel.getServiceName()).thenReturn("org.apache.dubbo.BarService");
-        ApplicationModel.initProviderModel("org.apache.dubbo.BarService", providerModel);
+        when(providerModel.getServiceMetadata()).thenReturn(new ServiceMetadata("org.apache.dubbo.qos.command.impl.TestInterface2", "ddd", "1.2.3.offline", TestInterface2.class));
+        when(providerModel.getServiceName()).thenReturn("org.apache.dubbo.qos.command.impl.TestInterface2");
+        ApplicationModel.initProviderModel("org.apache.dubbo.qos.command.impl.TestInterface2", providerModel);
 
         Invoker providerInvoker = mock(Invoker.class);
         URL registryUrl = mock(URL.class);
         when(registryUrl.toFullString()).thenReturn("test://localhost:8080");
         URL providerUrl = mock(URL.class);
-        when(providerUrl.getServiceKey()).thenReturn("org.apache.dubbo.BarService");
-        when(providerUrl.toFullString()).thenReturn("dubbo://localhost:8888/org.apache.dubbo.BarService");
+        String serviceKey = "ddd/org.apache.dubbo.qos.command.impl.TestInterface2:1.2.3.offline";
+        when(providerUrl.getServiceKey()).thenReturn(serviceKey);
+        when(providerUrl.toFullString()).thenReturn("dubbo://localhost:8888/org.apache.dubbo.qos.command.impl.TestInterface2?version=1.2.3.offline&group=ddd");
         when(providerInvoker.getUrl()).thenReturn(providerUrl);
+
         ProviderConsumerRegTable.registerProvider(providerInvoker, registryUrl, providerUrl);
-        for (ProviderInvokerWrapper wrapper : getProviderInvoker("org.apache.dubbo.BarService")) {
+        for (ProviderInvokerWrapper wrapper : getProviderInvoker(serviceKey)) {
             wrapper.setReg(true);
         }
 
@@ -57,10 +62,11 @@ public class OfflineTest {
         TestRegistryFactory.registry = registry;
 
         Offline offline = new Offline();
-        String output = offline.execute(mock(CommandContext.class), new String[]{"org.apache.dubbo.BarService"});
+        String output = offline.execute(mock(CommandContext.class), new String[]{"org.apache.dubbo.qos.command.impl.TestInterface2"});
         assertThat(output, containsString("OK"));
+
         Mockito.verify(registry).unregister(providerUrl);
-        for (ProviderInvokerWrapper wrapper : getProviderInvoker("org.apache.dubbo.BarService")) {
+        for (ProviderInvokerWrapper wrapper : getProviderInvoker(serviceKey)) {
             assertThat(wrapper.isReg(), is(false));
         }
 
diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/OnlineTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/OnlineTest.java
index 71132c0..08c21e5 100644
--- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/OnlineTest.java
+++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/OnlineTest.java
@@ -24,11 +24,13 @@ import org.apache.dubbo.registry.support.ProviderInvokerWrapper;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 import org.apache.dubbo.rpc.model.ProviderModel;
+import org.apache.dubbo.rpc.model.ServiceMetadata;
+
 import org.junit.jupiter.api.Test;
 
 import static org.apache.dubbo.registry.support.ProviderConsumerRegTable.getProviderInvoker;
-import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -37,25 +39,31 @@ public class OnlineTest {
     @Test
     public void testExecute() throws Exception {
         ProviderModel providerModel = mock(ProviderModel.class);
-        when(providerModel.getServiceName()).thenReturn("org.apache.dubbo.BarService");
-        ApplicationModel.initProviderModel("org.apache.dubbo.BarService", providerModel);
+        when(providerModel.getServiceMetadata()).thenReturn(new ServiceMetadata("org.apache.dubbo.qos.command.impl.TestInterface", "ddd", "1.2.3.online", TestInterface.class));
+        when(providerModel.getServiceName()).thenReturn("org.apache.dubbo.qos.command.impl.TestInterface");
+        ApplicationModel.initProviderModel("org.apache.dubbo.qos.command.impl.TestInterface", providerModel);
 
         Invoker providerInvoker = mock(Invoker.class);
         URL registryUrl = mock(URL.class);
         when(registryUrl.toFullString()).thenReturn("test://localhost:8080");
         URL providerUrl = mock(URL.class);
-        when(providerUrl.getServiceKey()).thenReturn("org.apache.dubbo.BarService");
-        when(providerUrl.toFullString()).thenReturn("dubbo://localhost:8888/org.apache.dubbo.BarService");
+
+        String serviceKey = "ddd/org.apache.dubbo.qos.command.impl.TestInterface:1.2.3.online";
+        when(providerUrl.getServiceKey()).thenReturn(serviceKey);
+        when(providerUrl.toFullString()).thenReturn("dubbo://localhost:8888/org.apache.dubbo.qos.command.impl.TestInterface?version=1.2.3.online&group=ddd");
         when(providerInvoker.getUrl()).thenReturn(providerUrl);
         ProviderConsumerRegTable.registerProvider(providerInvoker, registryUrl, providerUrl);
 
         Registry registry = mock(Registry.class);
         TestRegistryFactory.registry = registry;
 
+        for (ProviderInvokerWrapper wrapper : getProviderInvoker(serviceKey)) {
+            assertTrue(!wrapper.isReg());
+        }
         Online online = new Online();
-        String output = online.execute(mock(CommandContext.class), new String[]{"org.apache.dubbo.BarService"});
+        String output = online.execute(mock(CommandContext.class), new String[]{"org.apache.dubbo.qos.command.impl.TestInterface"});
         assertThat(output, equalTo("OK"));
-        for (ProviderInvokerWrapper wrapper : getProviderInvoker("org.apache.dubbo.BarService")) {
+        for (ProviderInvokerWrapper wrapper : getProviderInvoker(serviceKey)) {
             assertTrue(wrapper.isReg());
         }
     }
diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/TestInterface.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/TestInterface.java
new file mode 100644
index 0000000..9a8eb0a
--- /dev/null
+++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/TestInterface.java
@@ -0,0 +1,9 @@
+package org.apache.dubbo.qos.command.impl;
+
+/**
+ * 2019-10-11
+ */
+public interface TestInterface {
+
+    String sayHello();
+}
diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/TestInterface2.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/TestInterface2.java
new file mode 100644
index 0000000..49ee892
--- /dev/null
+++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/TestInterface2.java
@@ -0,0 +1,9 @@
+package org.apache.dubbo.qos.command.impl;
+
+/**
+ * 2019-10-11
+ */
+public interface TestInterface2 {
+
+    String sayHello();
+}


[dubbo] 01/12: refactor online and offline

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo.git

commit 288aa4a417d25fbc936abb09ae17802bc75e9459
Author: cvictory <sh...@gmail.com>
AuthorDate: Thu Oct 10 15:10:48 2019 +0800

    refactor online and offline
---
 .../org/apache/dubbo/common/ServiceDescriptor.java | 94 ++++++++++++++++++++++
 .../src/main/java/org/apache/dubbo/common/URL.java | 10 +--
 .../org/apache/dubbo/qos/command/impl/Offline.java | 23 +++---
 .../org/apache/dubbo/qos/command/impl/Online.java  | 24 +++---
 .../apache/dubbo/rpc/model/ServiceMetadata.java    | 42 ++--------
 5 files changed, 129 insertions(+), 64 deletions(-)

diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/ServiceDescriptor.java b/dubbo-common/src/main/java/org/apache/dubbo/common/ServiceDescriptor.java
new file mode 100644
index 0000000..c072141
--- /dev/null
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/ServiceDescriptor.java
@@ -0,0 +1,94 @@
+package org.apache.dubbo.common;
+
+import org.apache.dubbo.common.utils.StringUtils;
+
+/**
+ * 2019-10-10
+ */
+public class ServiceDescriptor {
+    public static final char COLON_SEPERATOR = ':';
+
+    protected String serviceKey;
+    protected String serviceInterfaceName;
+    protected String version;
+    protected volatile String group;
+
+    public static String buildServiceKey(String path, String group, String version) {
+        StringBuilder buf = new StringBuilder();
+        if (group != null && group.length() > 0) {
+            buf.append(group).append("/");
+        }
+        buf.append(path);
+        if (version != null && version.length() > 0) {
+            buf.append(":").append(version);
+        }
+        return buf.toString();
+    }
+
+    /**
+     * Format : interface:version:group
+     *
+     * @return
+     */
+    public String getDisplayServiceKey() {
+        StringBuilder serviceNameBuilder = new StringBuilder();
+        serviceNameBuilder.append(serviceInterfaceName);
+        serviceNameBuilder.append(COLON_SEPERATOR).append(version);
+        serviceNameBuilder.append(COLON_SEPERATOR).append(group);
+        return serviceNameBuilder.toString();
+    }
+
+    public static ServiceDescriptor revertDisplayServiceKey(String displayKey) {
+        String[] eles = StringUtils.split(displayKey, COLON_SEPERATOR);
+        if (eles == null || eles.length < 1 || eles.length > 3) {
+            return new ServiceDescriptor();
+        }
+        ServiceDescriptor serviceDescriptor = new ServiceDescriptor();
+        serviceDescriptor.setServiceInterfaceName(eles[0]);
+        if (eles.length > 1) {
+            serviceDescriptor.setVersion(eles[1]);
+        }
+        if (eles.length == 3) {
+            serviceDescriptor.setGroup(eles[2]);
+        }
+
+        return serviceDescriptor;
+    }
+
+    public String getServiceKey() {
+        return serviceKey;
+    }
+
+    public void generateServiceKey() {
+        this.serviceKey = buildServiceKey(serviceInterfaceName, group, version);
+    }
+
+    public void setServiceKey(String serviceKey) {
+        this.serviceKey = serviceKey;
+    }
+
+    public String getServiceInterfaceName() {
+        return serviceInterfaceName;
+    }
+
+    public void setServiceInterfaceName(String serviceInterfaceName) {
+        this.serviceInterfaceName = serviceInterfaceName;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    public String getGroup() {
+        return group;
+    }
+
+    public void setGroup(String group) {
+        this.group = group;
+    }
+
+}
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java b/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java
index 8da1f53..6a34fdd 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java
@@ -1294,15 +1294,7 @@ class URL implements Serializable {
     }
 
     public static String buildKey(String path, String group, String version) {
-        StringBuilder buf = new StringBuilder();
-        if (group != null && group.length() > 0) {
-            buf.append(group).append("/");
-        }
-        buf.append(path);
-        if (version != null && version.length() > 0) {
-            buf.append(":").append(version);
-        }
-        return buf.toString();
+        return ServiceDescriptor.buildServiceKey(path, group, version);
     }
 
     public String toServiceStringWithoutResolving() {
diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Offline.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Offline.java
index 79c41f3..c44cc41 100644
--- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Offline.java
+++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Offline.java
@@ -38,7 +38,7 @@ import java.util.Set;
 })
 public class Offline implements BaseCommand {
     private Logger logger = LoggerFactory.getLogger(Offline.class);
-    private RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
+    private static RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
 
     @Override
     public String execute(CommandContext commandContext, String[] args) {
@@ -47,13 +47,23 @@ public class Offline implements BaseCommand {
         if (args != null && args.length > 0) {
             servicePattern = args[0];
         }
-        boolean hasService = false;
+        boolean hasService = offline(servicePattern);
+
+        if (hasService) {
+            return "OK";
+        } else {
+            return "service not found";
+        }
+    }
 
+    public static boolean offline(String servicePattern) {
+        boolean hasService = false;
         Collection<ProviderModel> providerModelList = ApplicationModel.allProviderModels();
         for (ProviderModel providerModel : providerModelList) {
             if (providerModel.getServiceName().matches(servicePattern)) {
                 hasService = true;
-                Set<ProviderInvokerWrapper> providerInvokerWrapperSet = ProviderConsumerRegTable.getProviderInvoker(providerModel.getServiceName());
+                Set<ProviderInvokerWrapper> providerInvokerWrapperSet = ProviderConsumerRegTable
+                        .getProviderInvoker(providerModel.getServiceMetadata().getServiceKey());
                 for (ProviderInvokerWrapper providerInvokerWrapper : providerInvokerWrapperSet) {
                     if (!providerInvokerWrapper.isReg()) {
                         continue;
@@ -64,11 +74,6 @@ public class Offline implements BaseCommand {
                 }
             }
         }
-
-        if (hasService) {
-            return "OK";
-        } else {
-            return "service not found";
-        }
+        return hasService;
     }
 }
diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Online.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Online.java
index 30ba14b..c72098f 100644
--- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Online.java
+++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Online.java
@@ -39,7 +39,7 @@ import java.util.Set;
 })
 public class Online implements BaseCommand {
     private Logger logger = LoggerFactory.getLogger(Online.class);
-    private RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
+    private static RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
 
     @Override
     public String execute(CommandContext commandContext, String[] args) {
@@ -49,13 +49,23 @@ public class Online implements BaseCommand {
             servicePattern = args[0];
         }
 
-        boolean hasService = false;
+        boolean hasService = online(servicePattern);
+
+        if (hasService) {
+            return "OK";
+        } else {
+            return "service not found";
+        }
+
+    }
 
+    public static boolean online(String servicePattern){
+        boolean hasService = false;
         Collection<ProviderModel> providerModelList = ApplicationModel.allProviderModels();
         for (ProviderModel providerModel : providerModelList) {
             if (providerModel.getServiceName().matches(servicePattern)) {
                 hasService = true;
-                Set<ProviderInvokerWrapper> providerInvokerWrapperSet = ProviderConsumerRegTable.getProviderInvoker(providerModel.getServiceName());
+                Set<ProviderInvokerWrapper> providerInvokerWrapperSet = ProviderConsumerRegTable.getProviderInvoker(providerModel.getServiceMetadata().getServiceKey());
                 for (ProviderInvokerWrapper providerInvokerWrapper : providerInvokerWrapperSet) {
                     if (providerInvokerWrapper.isReg()) {
                         continue;
@@ -66,12 +76,6 @@ public class Online implements BaseCommand {
                 }
             }
         }
-
-        if (hasService) {
-            return "OK";
-        } else {
-            return "service not found";
-        }
-
+        return hasService;
     }
 }
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/model/ServiceMetadata.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/model/ServiceMetadata.java
index 5a09f45..0bf34d2 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/model/ServiceMetadata.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/model/ServiceMetadata.java
@@ -16,6 +16,9 @@
  */
 package org.apache.dubbo.rpc.model;
 
+import org.apache.dubbo.common.ServiceDescriptor;
+import org.apache.dubbo.common.URL;
+
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -23,16 +26,11 @@ import java.util.concurrent.ConcurrentHashMap;
  * data related to service level such as name, version, classloader of business service,
  * security info, etc. Also with a AttributeMap for extension.
  */
-public class ServiceMetadata {
+public class ServiceMetadata extends ServiceDescriptor {
 
-    private String serviceKey;
-    private String serviceInterfaceName;
     private String defaultGroup;
-    private String version;
     private Class<?> serviceType;
 
-    private volatile String group;
-
     private Object target;
 
     /* will be transferred to remote side */
@@ -45,7 +43,7 @@ public class ServiceMetadata {
         this.defaultGroup = group;
         this.group = group;
         this.version = version;
-        this.serviceKey = serviceInterfaceName + ":" + version;
+        this.serviceKey = URL.buildKey(serviceInterfaceName, group, version);
         this.serviceType = serviceType;
     }
 
@@ -53,7 +51,7 @@ public class ServiceMetadata {
     }
 
     public String getServiceKey() {
-        return serviceInterfaceName + ":" + version;
+        return serviceKey;
     }
 
     public Map<String, Object> getAttachments() {
@@ -80,46 +78,18 @@ public class ServiceMetadata {
         return serviceType;
     }
 
-    public String getServiceInterfaceName() {
-        return serviceInterfaceName;
-    }
-
     public String getDefaultGroup() {
         return defaultGroup;
     }
 
-    public String getVersion() {
-        return version;
-    }
-
-    public String getGroup() {
-        return group;
-    }
-
-    public void setGroup(String group) {
-        this.group = group;
-    }
-
-    public void setServiceInterfaceName(String serviceInterfaceName) {
-        this.serviceInterfaceName = serviceInterfaceName;
-    }
-
     public void setDefaultGroup(String defaultGroup) {
         this.defaultGroup = defaultGroup;
     }
 
-    public void setVersion(String version) {
-        this.version = version;
-    }
-
     public void setServiceType(Class<?> serviceType) {
         this.serviceType = serviceType;
     }
 
-    public void setServiceKey(String serviceKey) {
-        this.serviceKey = serviceKey;
-    }
-
     public Object getTarget() {
         return target;
     }


[dubbo] 03/12: ExtensionLoader try to load resource from itself ClassLoader first

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo.git

commit c30a430ae4fe07491ab16f6aeb0238b727ad5101
Author: hengyunabc <he...@gmail.com>
AuthorDate: Thu Oct 10 19:52:02 2019 +0800

    ExtensionLoader try to load resource from itself ClassLoader first
---
 .../dubbo/common/extension/ExtensionLoader.java    | 27 ++++++++++++----------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java
index 47b19cf..bc4739d 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java
@@ -660,21 +660,24 @@ public class ExtensionLoader<T> {
     private void loadDirectory(Map<String, Class<?>> extensionClasses, String dir, String type) {
         String fileName = dir + type;
         try {
-            Enumeration<java.net.URL> urls;
+            Enumeration<java.net.URL> urls = null;
             ClassLoader classLoader = findClassLoader();
-            if (classLoader != null) {
-                urls = classLoader.getResources(fileName);
-            } else {
-                urls = ClassLoader.getSystemResources(fileName);
+            
+            // try to load from ExtensionLoader's ClassLoader first
+            ClassLoader extensionLoaderClassLoader = ExtensionLoader.class.getClassLoader();
+            if (ClassLoader.getSystemClassLoader() != extensionLoaderClassLoader) {
+                urls = extensionLoaderClassLoader.getResources(fileName);
             }
-            if (urls != null) {
-                if (!urls.hasMoreElements()) {
-                    // try to load from ExtensionLoader's ClassLoader
-                    ClassLoader extensionLoaderClassLoader = this.getClass().getClassLoader();
-                    if (ClassLoader.getSystemClassLoader() != extensionLoaderClassLoader) {
-                        urls = extensionLoaderClassLoader.getResources(fileName);
-                    }
+            
+            if(urls == null || !urls.hasMoreElements()) {
+                if (classLoader != null) {
+                    urls = classLoader.getResources(fileName);
+                } else {
+                    urls = ClassLoader.getSystemResources(fileName);
                 }
+            }
+
+            if (urls != null) {
                 while (urls.hasMoreElements()) {
                     java.net.URL resourceURL = urls.nextElement();
                     loadResource(extensionClasses, classLoader, resourceURL);


[dubbo] 08/12: to process a scenario when service type is not available and service invocation is not generic either

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo.git

commit c18e6c367237584cc01c630141262cad9aae9595
Author: beiwei.ly <be...@alibaba-inc.com>
AuthorDate: Tue Oct 29 15:45:33 2019 +0800

    to process a scenario when service type is not available and service invocation is not generic either
---
 .../src/main/java/org/apache/dubbo/rpc/Invocation.java | 12 ++++++++++++
 .../main/java/org/apache/dubbo/rpc/RpcInvocation.java  | 18 ++++++++++++++++++
 .../org/apache/dubbo/rpc/filter/GenericImplFilter.java |  2 ++
 .../java/org/apache/dubbo/rpc/support/RpcUtils.java    |  2 +-
 4 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Invocation.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Invocation.java
index 96520d3..d5a24b0 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Invocation.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Invocation.java
@@ -17,6 +17,7 @@
 package org.apache.dubbo.rpc;
 
 import java.util.Map;
+import java.util.stream.Stream;
 
 /**
  * Invocation. (API, Prototype, NonThreadSafe)
@@ -46,6 +47,17 @@ public interface Invocation {
     Class<?>[] getParameterTypes();
 
     /**
+     * get parameter's signature, string representation of parameter types.
+     *
+     * @return parameter's signature
+     */
+    default String[] getParameterSignatures() {
+        return Stream.of(getParameterTypes())
+                .map(Class::getName)
+                .toArray(String[]::new);
+    }
+
+    /**
      * get arguments.
      *
      * @return arguments.
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcInvocation.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcInvocation.java
index fc63bae..b29ee56 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcInvocation.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcInvocation.java
@@ -23,6 +23,7 @@ import java.lang.reflect.Method;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.stream.Stream;
 
 import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
@@ -47,6 +48,8 @@ public class RpcInvocation implements Invocation, Serializable {
 
     private Class<?>[] parameterTypes;
 
+    private String[] parameterSignatures;
+
     private Object[] arguments;
 
     private Map<String, Object> attachments;
@@ -118,6 +121,10 @@ public class RpcInvocation implements Invocation, Serializable {
     public RpcInvocation(String methodName, Class<?>[] parameterTypes, Object[] arguments, Map<String, Object> attachments, Invoker<?> invoker) {
         this.methodName = methodName;
         this.parameterTypes = parameterTypes == null ? new Class<?>[0] : parameterTypes;
+        this.parameterSignatures = parameterTypes == null ? null :
+                Stream.of(getParameterTypes())
+                        .map(Class::getName)
+                        .toArray(String[]::new);
         this.arguments = arguments == null ? new Object[0] : arguments;
         this.attachments = attachments == null ? new HashMap<String, Object>() : attachments;
         this.invoker = invoker;
@@ -168,10 +175,21 @@ public class RpcInvocation implements Invocation, Serializable {
         return parameterTypes;
     }
 
+    @Override
+    public String[] getParameterSignatures() {
+        return  parameterSignatures;
+    }
+
     public void setParameterTypes(Class<?>[] parameterTypes) {
         this.parameterTypes = parameterTypes == null ? new Class<?>[0] : parameterTypes;
     }
 
+    // parameter signatures can be set independently, it is useful when the service type is not found on caller side and
+    // the invocation is not generic invocation either.
+    public void setParameterSignatures(String[] parameterSignatures) {
+        this.parameterSignatures = parameterSignatures;
+    }
+
     @Override
     public Object[] getArguments() {
         return arguments;
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java
index 0fd0d82..2277f27 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java
@@ -32,6 +32,7 @@ import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.RpcInvocation;
 import org.apache.dubbo.rpc.service.GenericException;
+import org.apache.dubbo.rpc.service.GenericService;
 import org.apache.dubbo.rpc.support.ProtocolUtils;
 import org.apache.dubbo.rpc.support.RpcUtils;
 
@@ -130,6 +131,7 @@ public class GenericImplFilter extends ListenableFilter {
             String methodName = invocation.getMethodName();
             Class<?>[] parameterTypes = invocation.getParameterTypes();
             if (ProtocolUtils.isGeneric(generic)
+                    && GenericService.class != invoker.getInterface()
                     && (!$INVOKE.equals(invocation.getMethodName()) && !$INVOKE_ASYNC.equals(invocation.getMethodName()))
                     && invocation instanceof RpcInvocation) {
                 if (!appResponse.hasException()) {
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/RpcUtils.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/RpcUtils.java
index 60ed621..94faa57 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/RpcUtils.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/RpcUtils.java
@@ -62,7 +62,7 @@ public class RpcUtils {
                 }
             }
         } catch (Throwable t) {
-            logger.warn(t.getMessage(), t);
+            // ignore
         }
         return null;
     }


[dubbo] 05/12: Merge branch 'merge-3.x' of github.com:chickenlj/incubator-dubbo into merge-3.x

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo.git

commit 88c23867ac3641eba43c848714882ffc5896bedd
Merge: b797852 c30a430
Author: cvictory <sh...@gmail.com>
AuthorDate: Sat Oct 12 14:56:18 2019 +0800

    Merge branch 'merge-3.x' of github.com:chickenlj/incubator-dubbo into merge-3.x

 .../dubbo/common/extension/ExtensionLoader.java    | 27 ++++++++++++----------
 1 file changed, 15 insertions(+), 12 deletions(-)


[dubbo] 09/12: enhance generic invocation check

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo.git

commit 0ad3577dd40b535e38d7262a544d1f705015edab
Author: beiwei.ly <be...@alibaba-inc.com>
AuthorDate: Tue Oct 29 16:33:42 2019 +0800

    enhance generic invocation check
---
 .../src/main/java/org/apache/dubbo/rpc/support/RpcUtils.java         | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/RpcUtils.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/RpcUtils.java
index 94faa57..7e0da8f 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/RpcUtils.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/RpcUtils.java
@@ -24,6 +24,7 @@ import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.InvokeMode;
 import org.apache.dubbo.rpc.RpcInvocation;
+import org.apache.dubbo.rpc.service.GenericService;
 
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
@@ -48,6 +49,7 @@ public class RpcUtils {
         try {
             if (invocation != null && invocation.getInvoker() != null
                     && invocation.getInvoker().getUrl() != null
+                    && invocation.getInvoker().getInterface() != GenericService.class
                     && !invocation.getMethodName().startsWith("$")) {
                 String service = invocation.getInvoker().getUrl().getServiceInterface();
                 if (StringUtils.isNotEmpty(service)) {
@@ -62,7 +64,7 @@ public class RpcUtils {
                 }
             }
         } catch (Throwable t) {
-            // ignore
+            logger.warn(t.getMessage(), t);
         }
         return null;
     }
@@ -71,6 +73,7 @@ public class RpcUtils {
         try {
             if (invocation != null && invocation.getInvoker() != null
                     && invocation.getInvoker().getUrl() != null
+                    && invocation.getInvoker().getInterface() != GenericService.class
                     && !invocation.getMethodName().startsWith("$")) {
                 String service = invocation.getInvoker().getUrl().getServiceInterface();
                 if (StringUtils.isNotEmpty(service)) {


[dubbo] 10/12: to process a scenario when service type is not available and service invocation is not generic either

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo.git

commit e826d0864b95a03a013f5c0d270d5c9bb3ca454d
Merge: 128a50a 0ad3577
Author: ken.lj <ke...@gmail.com>
AuthorDate: Thu Oct 31 16:21:38 2019 +0800

    to process a scenario when service type is not available and service invocation is not generic either
    
    to process a scenario when service type is not available and service invocation is not generic either

 .../src/main/java/org/apache/dubbo/rpc/Invocation.java | 12 ++++++++++++
 .../main/java/org/apache/dubbo/rpc/RpcInvocation.java  | 18 ++++++++++++++++++
 .../org/apache/dubbo/rpc/filter/GenericImplFilter.java |  2 ++
 .../java/org/apache/dubbo/rpc/support/RpcUtils.java    |  3 +++
 4 files changed, 35 insertions(+)


[dubbo] 12/12: generic codec & bootstrap api

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo.git

commit 02eabd6369400fd61db29ca44492678af745bccd
Author: ken.lj <ke...@gmail.com>
AuthorDate: Sun Nov 3 13:26:07 2019 +0800

    generic codec & bootstrap api
---
 .../org/apache/dubbo/bootstrap/DubboBootstrap.java |  9 +++++
 .../org/apache/dubbo/config/ReferenceConfig.java   |  8 ++++-
 .../org/apache/dubbo/config/ServiceConfig.java     |  8 ++++-
 .../dubbo/config/utils/ReferenceConfigCache.java   |  2 ++
 .../apache/dubbo/config/spring/ReferenceBean.java  |  5 +++
 .../configcenter/DynamicConfigurationFactory.java  |  2 +-
 .../dubbo/common/constants/CommonConstants.java    |  2 ++
 .../apache/dubbo/common/utils/ReflectUtils.java    | 10 ++++++
 .../dubbo/config/service/ReferenceConfig.java      |  5 +--
 .../apache/dubbo/rpc/model/MethodDescriptor.java   |  9 ++++-
 .../store/InMemoryWritableMetadataService.java     |  5 ++-
 .../store/RemoteWritableMetadataService.java       |  5 ++-
 .../org/apache/dubbo/qos/command/impl/Offline.java | 38 +++++++++------------
 .../org/apache/dubbo/qos/command/impl/Online.java  | 39 +++++++++-------------
 .../org/apache/dubbo/rpc/ClusterInterceptor.java   | 11 +++++-
 .../src/main/java/org/apache/dubbo/rpc/Filter.java | 25 +++++++-------
 .../main/java/org/apache/dubbo/rpc/Invocation.java |  2 +-
 .../java/org/apache/dubbo/rpc/RpcInvocation.java   | 12 +++++++
 .../apache/dubbo/rpc/filter/GenericImplFilter.java | 39 ++++++++++++++++------
 .../org/apache/dubbo/rpc/support/RpcUtils.java     | 18 ++++++++++
 .../protocol/dubbo/DecodeableRpcInvocation.java    | 37 +++++++++++---------
 .../dubbo/rpc/protocol/dubbo/DubboCodec.java       |  3 +-
 22 files changed, 198 insertions(+), 96 deletions(-)

diff --git a/dubbo-bootstrap/dubbo-bootstrap-api/src/main/java/org/apache/dubbo/bootstrap/DubboBootstrap.java b/dubbo-bootstrap/dubbo-bootstrap-api/src/main/java/org/apache/dubbo/bootstrap/DubboBootstrap.java
index 6281366..d537537 100644
--- a/dubbo-bootstrap/dubbo-bootstrap-api/src/main/java/org/apache/dubbo/bootstrap/DubboBootstrap.java
+++ b/dubbo-bootstrap/dubbo-bootstrap-api/src/main/java/org/apache/dubbo/bootstrap/DubboBootstrap.java
@@ -550,6 +550,14 @@ public class DubboBootstrap extends GenericEventListener {
         }
     }
 
+    public boolean isExported(ServiceConfig<?> serviceConfig) {
+        return CollectionUtils.isNotEmpty(exporters.get(serviceConfig));
+    }
+
+    public boolean isRefereed(ReferenceConfig<?> referenceConfig) {
+        return getCache().get(referenceConfig) != null;
+    }
+
     /**
      * refer a single ReferenceConfig
      * <p>
@@ -1257,6 +1265,7 @@ public class DubboBootstrap extends GenericEventListener {
                 }
             }
             sc.setInterface(interfaceClass);
+            sc.setInterface(interfaceName);
             sc.checkStubAndLocal(interfaceClass);
             BootstrapUtils.checkMock(interfaceClass, sc);
             sc.appendParameters();
diff --git a/dubbo-bootstrap/dubbo-bootstrap-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java b/dubbo-bootstrap/dubbo-bootstrap-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
index 047f8a4..654d5e9 100644
--- a/dubbo-bootstrap/dubbo-bootstrap-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
+++ b/dubbo-bootstrap/dubbo-bootstrap-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
@@ -24,12 +24,18 @@ import org.apache.dubbo.bootstrap.DubboBootstrap;
  */
 @Deprecated
 public class ReferenceConfig<T> extends org.apache.dubbo.config.service.ReferenceConfig<T> {
+    DubboBootstrap bootstrap = DubboBootstrap.getInstance();
 
+    @Deprecated
     public synchronized T get() {
-        DubboBootstrap bootstrap = DubboBootstrap.getInstance();
         // bootstrap guarantees only started once.
         bootstrap.start();
         return (T) bootstrap.refer(this);
     }
 
+    @Deprecated
+    public void destroy() {
+        bootstrap.unRefer(this);
+    }
+
 }
diff --git a/dubbo-bootstrap/dubbo-bootstrap-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java b/dubbo-bootstrap/dubbo-bootstrap-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
index 29cb5a3..3921318 100644
--- a/dubbo-bootstrap/dubbo-bootstrap-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
+++ b/dubbo-bootstrap/dubbo-bootstrap-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
@@ -25,12 +25,18 @@ import org.apache.dubbo.bootstrap.DubboBootstrap;
 @Deprecated
 public class ServiceConfig<T> extends org.apache.dubbo.config.service.ServiceConfig<T> {
 
+    private DubboBootstrap bootstrap = DubboBootstrap.getInstance();
+
     @Deprecated
     public void export() {
-        DubboBootstrap bootstrap = DubboBootstrap.getInstance();
         // bootstrap guarantees only started once.
         bootstrap.start();
         bootstrap.export(this);
     }
 
+    @Deprecated
+    public void unexport() {
+        bootstrap.unExport(this);
+    }
+
 }
\ No newline at end of file
diff --git a/dubbo-bootstrap/dubbo-bootstrap-api/src/main/java/org/apache/dubbo/config/utils/ReferenceConfigCache.java b/dubbo-bootstrap/dubbo-bootstrap-api/src/main/java/org/apache/dubbo/config/utils/ReferenceConfigCache.java
index 925e1e9..2e40b7b 100644
--- a/dubbo-bootstrap/dubbo-bootstrap-api/src/main/java/org/apache/dubbo/config/utils/ReferenceConfigCache.java
+++ b/dubbo-bootstrap/dubbo-bootstrap-api/src/main/java/org/apache/dubbo/config/utils/ReferenceConfigCache.java
@@ -538,6 +538,7 @@ public class ReferenceConfigCache {
                 rc.setGeneric(rc.getConsumer().getGeneric());
             }
             Class<?> interfaceClass = null;
+            String realInterfaceName = rc.getInterface();
             if (ProtocolUtils.isGeneric(rc.getGeneric())) {
                 interfaceClass = GenericService.class;
             } else {
@@ -550,6 +551,7 @@ public class ReferenceConfigCache {
                 rc.checkInterfaceAndMethods(interfaceClass, rc.getMethods());
             }
             rc.setInterface(interfaceClass);
+            rc.setInterface(realInterfaceName);
             rc.resolveFile();
             rc.checkApplication();
             rc.checkMetadataReport();
diff --git a/dubbo-bootstrap/dubbo-bootstrap-spring/src/main/java/org/apache/dubbo/config/spring/ReferenceBean.java b/dubbo-bootstrap/dubbo-bootstrap-spring/src/main/java/org/apache/dubbo/config/spring/ReferenceBean.java
index 26ca08e..9207421 100644
--- a/dubbo-bootstrap/dubbo-bootstrap-spring/src/main/java/org/apache/dubbo/config/spring/ReferenceBean.java
+++ b/dubbo-bootstrap/dubbo-bootstrap-spring/src/main/java/org/apache/dubbo/config/spring/ReferenceBean.java
@@ -76,6 +76,11 @@ public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean,
             BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ConfigCenterBean.class, false, false);
         }
 
+        // lazy init by default.
+        if (init == null) {
+            init = false;
+        }
+
         // eager init if necessary.
         if (shouldInit()) {
             getObject();
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/DynamicConfigurationFactory.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/DynamicConfigurationFactory.java
index 649eec6..ae4a8ee 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/DynamicConfigurationFactory.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/DynamicConfigurationFactory.java
@@ -25,7 +25,7 @@ import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoad
 /**
  * The factory interface to create the instance of {@link DynamicConfiguration}
  */
-@SPI("file") // 2.7.4 change the default SPI implementation
+@SPI("nop")
 public interface DynamicConfigurationFactory {
 
     DynamicConfiguration getDynamicConfiguration(URL url);
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
index e859f50..a8b2037 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
@@ -288,4 +288,6 @@ public interface CommonConstants {
 
     String REGISTER_KEY = "register";
 
+    String DUBBO_INVOCATION_PREFIX = "_DUBBO_IGNORE_ATTACH_";
+
 }
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ReflectUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ReflectUtils.java
index 6d92210..18201d8 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ReflectUtils.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ReflectUtils.java
@@ -428,6 +428,16 @@ public final class ReflectUtils {
         return ret.toString();
     }
 
+    public static String[] getDescArray(final Method m) {
+        Class<?>[] parameterTypes = m.getParameterTypes();
+        String[] arr = new String[parameterTypes.length];
+
+        for (int i = 0; i < parameterTypes.length; i++) {
+            arr[i] = getDesc(parameterTypes[i]);
+        }
+        return arr;
+    }
+
     /**
      * get constructor desc.
      * "()V", "(Ljava/lang/String;I)V"
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/service/ReferenceConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/service/ReferenceConfig.java
index e624a2b..a0da2bf 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/config/service/ReferenceConfig.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/config/service/ReferenceConfig.java
@@ -131,8 +131,9 @@ public class ReferenceConfig<T> extends AbstractReferenceConfig {
             shouldInit = getConsumer().isInit();
         }
         if (shouldInit == null) {
-            // default is false
-            return false;
+            // default is true, spring will still init lazily by setting init's default value to false,
+            // the def default setting happens in {@link ReferenceBean#afterPropertiesSet}.
+            return true;
         }
         return shouldInit;
     }
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/MethodDescriptor.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/MethodDescriptor.java
index de0f7cf..cd5bf91 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/MethodDescriptor.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/MethodDescriptor.java
@@ -32,6 +32,8 @@ public class MethodDescriptor {
     //    private final boolean isCallBack;
 //    private final boolean isFuture;
     private final String paramDesc;
+    // duplicate filed as paramDesc, but with different format.
+    private final String[] compatibleParamSignatures;
     private final Class<?>[] parameterClasses;
     private final Class<?> returnClass;
     private final Type[] returnTypes;
@@ -43,7 +45,8 @@ public class MethodDescriptor {
         this.parameterClasses = method.getParameterTypes();
         this.returnClass = method.getReturnType();
         this.returnTypes = ReflectUtils.getReturnTypes(method);
-        this.paramDesc = ReflectUtils.getDesc(method);
+        this.paramDesc = ReflectUtils.getDesc(parameterClasses);
+        this.compatibleParamSignatures = ReflectUtils.getDescArray(method);
         this.methodName = method.getName();
         this.generic = (methodName.equals($INVOKE) || methodName.equals($INVOKE_ASYNC)) && parameterClasses.length == 3;
     }
@@ -60,6 +63,10 @@ public class MethodDescriptor {
         return paramDesc;
     }
 
+    public String[] getCompatibleParamSignatures() {
+        return compatibleParamSignatures;
+    }
+
     public Class<?>[] getParameterClasses() {
         return parameterClasses;
     }
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/InMemoryWritableMetadataService.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/InMemoryWritableMetadataService.java
index 115fab8..ede7b59 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/InMemoryWritableMetadataService.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/InMemoryWritableMetadataService.java
@@ -24,6 +24,7 @@ import org.apache.dubbo.metadata.MetadataService;
 import org.apache.dubbo.metadata.WritableMetadataService;
 import org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
 import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
+import org.apache.dubbo.rpc.support.ProtocolUtils;
 
 import com.google.gson.Gson;
 
@@ -44,6 +45,7 @@ import static org.apache.dubbo.common.URL.buildKey;
 import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
 import static org.apache.dubbo.common.utils.CollectionUtils.isEmpty;
+import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
 
 /**
  * The {@link WritableMetadataService} implementation stores the metadata of Dubbo services in memory locally when they
@@ -122,7 +124,8 @@ public class InMemoryWritableMetadataService implements WritableMetadataService
     public void publishServiceDefinition(URL providerUrl) {
         try {
             String interfaceName = providerUrl.getParameter(INTERFACE_KEY);
-            if (StringUtils.isNotEmpty(interfaceName)) {
+            if (StringUtils.isNotEmpty(interfaceName)
+                    && !ProtocolUtils.isGeneric(providerUrl.getParameter(GENERIC_KEY))) {
                 Class interfaceClass = Class.forName(interfaceName);
                 ServiceDefinition serviceDefinition = ServiceDefinitionBuilder.build(interfaceClass);
                 Gson gson = new Gson();
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/RemoteWritableMetadataService.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/RemoteWritableMetadataService.java
index 22c028d..609d43f 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/RemoteWritableMetadataService.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/RemoteWritableMetadataService.java
@@ -32,6 +32,7 @@ import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
 import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
 import org.apache.dubbo.remoting.Constants;
 import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.support.ProtocolUtils;
 
 import java.util.Iterator;
 import java.util.Set;
@@ -47,6 +48,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
 import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
+import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
 
 /**
  * The {@link WritableMetadataService} implementation stores the metadata of Dubbo services in metadata center when they
@@ -74,7 +76,8 @@ public class RemoteWritableMetadataService implements WritableMetadataService {
     public void publishServiceDefinition(URL providerUrl) {
         try {
             String interfaceName = providerUrl.getParameter(INTERFACE_KEY);
-            if (StringUtils.isNotEmpty(interfaceName)) {
+            if (StringUtils.isNotEmpty(interfaceName)
+                    && !ProtocolUtils.isGeneric(providerUrl.getParameter(GENERIC_KEY))) {
                 Class interfaceClass = Class.forName(interfaceName);
                 ServiceDefinition serviceDefinition = ServiceDefinitionBuilder.build(interfaceClass);
                 getMetadataReport().storeProviderMetadata(new MetadataIdentifier(providerUrl.getServiceInterface(),
diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Offline.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Offline.java
index aa236a7..eae4aca 100644
--- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Offline.java
+++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Offline.java
@@ -16,8 +16,6 @@
  */
 package org.apache.dubbo.qos.command.impl;
 
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.URLBuilder;
 import org.apache.dubbo.common.extension.ExtensionLoader;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
@@ -26,8 +24,6 @@ import org.apache.dubbo.qos.command.CommandContext;
 import org.apache.dubbo.qos.command.annotation.Cmd;
 import org.apache.dubbo.registry.Registry;
 import org.apache.dubbo.registry.RegistryFactory;
-import org.apache.dubbo.registry.RegistryService;
-import org.apache.dubbo.registry.support.AbstractRegistryFactory;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 import org.apache.dubbo.rpc.model.ProviderModel;
 import org.apache.dubbo.rpc.model.ServiceRepository;
@@ -35,18 +31,14 @@ import org.apache.dubbo.rpc.model.ServiceRepository;
 import java.util.Collection;
 import java.util.List;
 
-import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
-import static org.apache.dubbo.rpc.cluster.Constants.EXPORT_KEY;
-import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
-
 @Cmd(name = "offline", summary = "offline dubbo", example = {
         "offline dubbo",
         "offline xx.xx.xxx.service"
 })
 public class Offline implements BaseCommand {
     private Logger logger = LoggerFactory.getLogger(Offline.class);
-    private RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
-    private ServiceRepository serviceRepository = ApplicationModel.getServiceRepository();
+    private static RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
+    private static ServiceRepository serviceRepository = ApplicationModel.getServiceRepository();
 
     @Override
     public String execute(CommandContext commandContext, String[] args) {
@@ -55,6 +47,17 @@ public class Offline implements BaseCommand {
         if (args != null && args.length > 0) {
             servicePattern = args[0];
         }
+
+        boolean hasService = offline(servicePattern);
+
+        if (hasService) {
+            return "OK";
+        } else {
+            return "service not found";
+        }
+    }
+
+    public static boolean offline(String servicePattern) {
         boolean hasService = false;
 
         Collection<ProviderModel> providerModelList = serviceRepository.getExportedServices();
@@ -64,25 +67,14 @@ public class Offline implements BaseCommand {
                 List<ProviderModel.RegisterStatedURL> statedUrls = providerModel.getStatedUrl();
                 for (ProviderModel.RegisterStatedURL statedURL : statedUrls) {
                     if (statedURL.isRegistered()) {
-                        URL url = URLBuilder.from(statedURL.getRegistryUrl())
-                                .setPath(RegistryService.class.getName())
-                                .addParameter(INTERFACE_KEY, RegistryService.class.getName())
-                                .removeParameters(EXPORT_KEY, REFER_KEY)
-                                .build();
-                        String key = url.toServiceStringWithoutResolving();
-                        Registry registry = AbstractRegistryFactory.getRegistry(key);
+                        Registry registry = registryFactory.getRegistry(statedURL.getRegistryUrl());
                         registry.unregister(statedURL.getProviderUrl());
                         statedURL.setRegistered(false);
                     }
                 }
-
             }
         }
 
-        if (hasService) {
-            return "OK";
-        } else {
-            return "service not found";
-        }
+        return hasService;
     }
 }
diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Online.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Online.java
index 4f8598c..1f99dd5 100644
--- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Online.java
+++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Online.java
@@ -16,8 +16,6 @@
  */
 package org.apache.dubbo.qos.command.impl;
 
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.URLBuilder;
 import org.apache.dubbo.common.extension.ExtensionLoader;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
@@ -27,8 +25,6 @@ import org.apache.dubbo.qos.command.CommandContext;
 import org.apache.dubbo.qos.command.annotation.Cmd;
 import org.apache.dubbo.registry.Registry;
 import org.apache.dubbo.registry.RegistryFactory;
-import org.apache.dubbo.registry.RegistryService;
-import org.apache.dubbo.registry.support.AbstractRegistryFactory;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 import org.apache.dubbo.rpc.model.ProviderModel;
 import org.apache.dubbo.rpc.model.ServiceRepository;
@@ -36,18 +32,14 @@ import org.apache.dubbo.rpc.model.ServiceRepository;
 import java.util.Collection;
 import java.util.List;
 
-import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
-import static org.apache.dubbo.rpc.cluster.Constants.EXPORT_KEY;
-import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
-
 @Cmd(name = "online", summary = "online dubbo", example = {
         "online dubbo",
         "online xx.xx.xxx.service"
 })
 public class Online implements BaseCommand {
-    private Logger logger = LoggerFactory.getLogger(Online.class);
-    private RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
-    private ServiceRepository serviceRepository = ApplicationModel.getServiceRepository();
+    private static final Logger logger = LoggerFactory.getLogger(Online.class);
+    private static RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
+    private static ServiceRepository serviceRepository = ApplicationModel.getServiceRepository();
 
     @Override
     public String execute(CommandContext commandContext, String[] args) {
@@ -57,6 +49,15 @@ public class Online implements BaseCommand {
             servicePattern = args[0];
         }
 
+        boolean hasService = online(servicePattern);
+        if (hasService) {
+            return "OK";
+        } else {
+            return "service not found";
+        }
+    }
+
+    public static boolean online(String servicePattern) {
         boolean hasService = false;
 
         Collection<ProviderModel> providerModelList = serviceRepository.getExportedServices();
@@ -65,14 +66,8 @@ public class Online implements BaseCommand {
                 hasService = true;
                 List<ProviderModel.RegisterStatedURL> statedUrls = providerModel.getStatedUrl();
                 for (ProviderModel.RegisterStatedURL statedURL : statedUrls) {
-                    if (statedURL.isRegistered()) {
-                        URL url = URLBuilder.from(statedURL.getRegistryUrl())
-                                .setPath(RegistryService.class.getName())
-                                .addParameter(INTERFACE_KEY, RegistryService.class.getName())
-                                .removeParameters(EXPORT_KEY, REFER_KEY)
-                                .build();
-                        String key = url.toServiceStringWithoutResolving();
-                        Registry registry = AbstractRegistryFactory.getRegistry(key);
+                    if (!statedURL.isRegistered()) {
+                        Registry registry = registryFactory.getRegistry(statedURL.getRegistryUrl());
                         registry.register(statedURL.getProviderUrl());
                         statedURL.setRegistered(true);
                     }
@@ -80,10 +75,6 @@ public class Online implements BaseCommand {
             }
         }
 
-        if (hasService) {
-            return "OK";
-        } else {
-            return "service not found";
-        }
+        return hasService;
     }
 }
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/ClusterInterceptor.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/ClusterInterceptor.java
index a90b500..48cdcdd 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/ClusterInterceptor.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/ClusterInterceptor.java
@@ -19,7 +19,7 @@ package org.apache.dubbo.rpc;
 import org.apache.dubbo.common.extension.SPI;
 
 /**
- * Different from {@link Filter}, ClusterInterceptor works on the outmost layer, before one specific address/invoker is picked.
+ * Different from {@link Filter}, ClusterInterceptor works at the outmost layer, before one specific address/invoker is picked.
  */
 @SPI
 public interface ClusterInterceptor {
@@ -28,6 +28,15 @@ public interface ClusterInterceptor {
 
     void after(Invoker<?> invoker, Invocation invocation);
 
+    /**
+     * Does not need to override this method, override {@link #before(Invoker, Invocation)} and {@link #after(Invoker, Invocation)}
+     * methods to add your own logic expected to be executed before and after invoke.
+     *
+     * @param invoker
+     * @param invocation
+     * @return
+     * @throws RpcException
+     */
     default Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
         return invoker.invoke(invocation);
     }
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Filter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Filter.java
index 42158b7..72a50c7 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Filter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Filter.java
@@ -47,19 +47,20 @@ public interface Filter {
      */
     Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException;
 
-    interface Listener {
+    /**
+     * Please use {@link Listener#onMessage(Result, Invoker, Invocation)} instead.
+     * This method is kept only for compatibility and may get removed at any version in the future.
+     *
+     * @param appResponse
+     * @param invoker
+     * @param invocation
+     */
+    @Deprecated
+    default Result onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation) {
+        return appResponse;
+    }
 
-        /**
-         * Please use {@link #onMessage(Result, Invoker, Invocation)} instead.
-         * This method is kept only compatibility and may get removed at any version in the future.
-         *
-         * @param appResponse
-         * @param invoker
-         * @param invocation
-         */
-        @Deprecated
-        default void onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation) {
-        }
+    interface Listener {
 
         void onMessage(Result appResponse, Invoker<?> invoker, Invocation invocation);
 
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Invocation.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Invocation.java
index e54e115..02ba1f0 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Invocation.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Invocation.java
@@ -58,7 +58,7 @@ public interface Invocation {
      *
      * @return parameter's signature
      */
-    default String[] getParameterSignatures() {
+    default String[] getCompatibleParamSignatures() {
         return Stream.of(getParameterTypes())
                 .map(Class::getName)
                 .toArray(String[]::new);
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcInvocation.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcInvocation.java
index 960e091..978acbe 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcInvocation.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcInvocation.java
@@ -51,6 +51,7 @@ public class RpcInvocation implements Invocation, Serializable {
 
     private transient Class<?>[] parameterTypes;
     private String parameterTypesDesc;
+    private String[] compatibleParamSignatures;
 
     private Object[] arguments;
 
@@ -133,6 +134,7 @@ public class RpcInvocation implements Invocation, Serializable {
                     serviceModel.getMethod(methodName, parameterTypes)
                             .ifPresent(methodModel -> {
                                 this.parameterTypesDesc = methodModel.getParamDesc();
+                                this.compatibleParamSignatures = methodModel.getCompatibleParamSignatures();
                                 this.returnTypes = methodModel.getReturnTypes();
                             })
             );
@@ -205,6 +207,16 @@ public class RpcInvocation implements Invocation, Serializable {
         this.parameterTypesDesc = parameterTypesDesc;
     }
 
+    public String[] getCompatibleParamSignatures() {
+        return compatibleParamSignatures;
+    }
+
+    // parameter signatures can be set independently, it is useful when the service type is not found on caller side and
+    // the invocation is not generic invocation either.
+    public void setCompatibleParamSignatures(String[] compatibleParamSignatures) {
+        this.compatibleParamSignatures = compatibleParamSignatures;
+    }
+
     @Override
     public Object[] getArguments() {
         return arguments;
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java
index 579f21d..7b78c0c 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java
@@ -42,6 +42,7 @@ import java.lang.reflect.Type;
 
 import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE;
 import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE_ASYNC;
+import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_INVOCATION_PREFIX;
 import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
 
 /**
@@ -56,13 +57,21 @@ public class GenericImplFilter implements Filter, Filter.Listener {
 
     private static final String GENERIC_PARAMETER_DESC = "Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/Object;";
 
+    private static final String GENERIC_IMPL_MARKER = DUBBO_INVOCATION_PREFIX + "GENERIC_IMPL";
+
     @Override
     public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
         String generic = invoker.getUrl().getParameter(GENERIC_KEY);
-        if (ProtocolUtils.isGeneric(generic)
-                && (!$INVOKE.equals(invocation.getMethodName()) && !$INVOKE_ASYNC.equals(invocation.getMethodName()))
-                && invocation instanceof RpcInvocation) {
+        // calling a generic impl service
+        if (isCallingGenericImpl(generic, invocation)) {
             RpcInvocation invocation2 = new RpcInvocation(invocation);
+
+            /**
+             * Mark this invocation as a generic impl call, this value will be removed automatically before passing on the wire.
+             * See {@link RpcUtils#sieveUnnecessaryAttachments(Invocation)}
+             */
+            invocation2.setAttachment(GENERIC_IMPL_MARKER, true);
+
             String methodName = invocation2.getMethodName();
             Class<?>[] parameterTypes = invocation2.getParameterTypes();
             Object[] arguments = invocation2.getArguments();
@@ -91,10 +100,9 @@ public class GenericImplFilter implements Filter, Filter.Listener {
             invocation2.setParameterTypesDesc(GENERIC_PARAMETER_DESC);
             invocation2.setArguments(new Object[]{methodName, types, args});
             return invoker.invoke(invocation2);
-        } else if ((invocation.getMethodName().equals($INVOKE) || invocation.getMethodName().equals($INVOKE_ASYNC))
-                && invocation.getArguments() != null
-                && invocation.getArguments().length == 3
-                && ProtocolUtils.isGeneric(generic)) {
+        }
+        // making a generic call to a normal service
+        else if (isMakingGenericCall(generic, invocation)) {
 
             Object[] args = (Object[]) invocation.getArguments()[2];
             if (ProtocolUtils.isJavaGenericSerialization(generic)) {
@@ -127,9 +135,7 @@ public class GenericImplFilter implements Filter, Filter.Listener {
         String generic = invoker.getUrl().getParameter(GENERIC_KEY);
         String methodName = invocation.getMethodName();
         Class<?>[] parameterTypes = invocation.getParameterTypes();
-        if (ProtocolUtils.isGeneric(generic)
-                && (!$INVOKE.equals(invocation.getMethodName()) && !$INVOKE_ASYNC.equals(invocation.getMethodName()))
-                && invocation instanceof RpcInvocation) {
+        if (invocation.getAttachment(GENERIC_IMPL_MARKER) != null) {
             if (!appResponse.hasException()) {
                 Object value = appResponse.getValue();
                 try {
@@ -195,4 +201,17 @@ public class GenericImplFilter implements Filter, Filter.Listener {
 
     }
 
+    private boolean isCallingGenericImpl(String generic, Invocation invocation) {
+        return ProtocolUtils.isGeneric(generic)
+                && (!$INVOKE.equals(invocation.getMethodName()) && !$INVOKE_ASYNC.equals(invocation.getMethodName()))
+                && invocation instanceof RpcInvocation;
+    }
+
+    private boolean isMakingGenericCall(String generic, Invocation invocation) {
+        return (invocation.getMethodName().equals($INVOKE) || invocation.getMethodName().equals($INVOKE_ASYNC))
+                && invocation.getArguments() != null
+                && invocation.getArguments().length == 3
+                && ProtocolUtils.isGeneric(generic);
+    }
+
 }
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/RpcUtils.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/RpcUtils.java
index b1c6d15..7415928 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/RpcUtils.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/RpcUtils.java
@@ -28,11 +28,14 @@ import org.apache.dubbo.rpc.service.GenericService;
 
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.atomic.AtomicLong;
 
 import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE;
 import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE_ASYNC;
+import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_INVOCATION_PREFIX;
 import static org.apache.dubbo.rpc.Constants.ASYNC_KEY;
 import static org.apache.dubbo.rpc.Constants.AUTO_ATTACH_INVOCATIONID_KEY;
 import static org.apache.dubbo.rpc.Constants.ID_KEY;
@@ -184,6 +187,10 @@ public class RpcUtils {
         return $INVOKE_ASYNC.equals(inv.getMethodName());
     }
 
+    public static boolean isGenericCall(String path, String method) {
+        return $INVOKE.equals(method) || $INVOKE_ASYNC.equals(method);
+    }
+
     public static InvokeMode getInvokeMode(URL url, Invocation inv) {
         if (isReturnTypeFuture(inv)) {
             return InvokeMode.FUTURE;
@@ -203,4 +210,15 @@ public class RpcUtils {
         }
         return isOneway;
     }
+
+    public static Map<String, Object> sieveUnnecessaryAttachments(Invocation invocation) {
+        Map<String, Object> attachments = invocation.getAttachments();
+        Map<String, Object> attachmentsToPass = new HashMap<>(attachments.size());
+        for (Map.Entry<String, Object> entry : attachments.entrySet()) {
+            if (!entry.getKey().startsWith(DUBBO_INVOCATION_PREFIX)) {
+                attachmentsToPass.put(entry.getKey(), entry.getValue());
+            }
+        }
+        return attachmentsToPass;
+    }
 }
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcInvocation.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcInvocation.java
index 31c2bfc..d72a878 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcInvocation.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcInvocation.java
@@ -22,6 +22,7 @@ import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.common.serialize.Cleanable;
 import org.apache.dubbo.common.serialize.ObjectInput;
 import org.apache.dubbo.common.utils.Assert;
+import org.apache.dubbo.common.utils.ReflectUtils;
 import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.remoting.Channel;
 import org.apache.dubbo.remoting.Codec;
@@ -32,6 +33,7 @@ import org.apache.dubbo.rpc.RpcInvocation;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 import org.apache.dubbo.rpc.model.MethodDescriptor;
 import org.apache.dubbo.rpc.model.ServiceDescriptor;
+import org.apache.dubbo.rpc.support.RpcUtils;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -115,24 +117,27 @@ public class DecodeableRpcInvocation extends RpcInvocation implements Codec, Dec
             Object[] args = DubboCodec.EMPTY_OBJECT_ARRAY;
             Class<?>[] pts = DubboCodec.EMPTY_CLASS_ARRAY;
             if (desc.length() > 0) {
-                // TODO, lambda function requires variables to be final.
-                Optional<ServiceDescriptor> serviceModel = ApplicationModel.getServiceModel(path);
-                if (serviceModel.isPresent()) {
-                    Optional<MethodDescriptor> methodOptional = serviceModel.get().getMethod(getMethodName(), desc);
-                    if (methodOptional.isPresent()) {
-                        pts = methodOptional.get().getParameterClasses();
-                        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);
-                                }
-                            }
+                if (RpcUtils.isGenericCall(path, getMethodName())) {
+                    pts = ReflectUtils.desc2classArray(desc);
+                } else {
+                    Optional<ServiceDescriptor> serviceModel = ApplicationModel.getServiceModel(path);
+                    if (serviceModel.isPresent()) {
+                        Optional<MethodDescriptor> methodOptional = serviceModel.get().getMethod(getMethodName(), desc);
+                        if (methodOptional.isPresent()) {
+                            pts = methodOptional.get().getParameterClasses();
+                            this.setReturnTypes(methodOptional.get().getReturnTypes());
                         }
+                    }
+                }
 
-                        this.setReturnTypes(methodOptional.get().getReturnTypes());
+                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);
+                        }
                     }
                 }
             }
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCodec.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCodec.java
index 3716c45..ac4e53d 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCodec.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCodec.java
@@ -42,6 +42,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
 import static org.apache.dubbo.rpc.protocol.dubbo.CallbackServiceCodec.encodeInvocationArgument;
 import static org.apache.dubbo.rpc.protocol.dubbo.Constants.DECODE_IN_IO_THREAD_KEY;
 import static org.apache.dubbo.rpc.protocol.dubbo.Constants.DEFAULT_DECODE_IN_IO_THREAD;
+import static org.apache.dubbo.rpc.support.RpcUtils.sieveUnnecessaryAttachments;
 
 /**
  * Dubbo codec.
@@ -179,7 +180,7 @@ public class DubboCodec extends ExchangeCodec {
                 out.writeObject(encodeInvocationArgument(channel, inv, i));
             }
         }
-        out.writeAttachments(inv.getAttachments());
+        out.writeAttachments(sieveUnnecessaryAttachments(inv));
     }
 
     @Override


[dubbo] 02/12: Merge pull request #5 from cvictory/merge-3.x

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo.git

commit c152c3ce1114ebaee0a5717c21133c54a050d5cf
Merge: 7e0ef42 288aa4a
Author: ken.lj <ke...@gmail.com>
AuthorDate: Thu Oct 10 16:49:46 2019 +0800

    Merge pull request #5 from cvictory/merge-3.x
    
    refactor online and offline

 .../org/apache/dubbo/common/ServiceDescriptor.java | 94 ++++++++++++++++++++++
 .../src/main/java/org/apache/dubbo/common/URL.java | 10 +--
 .../org/apache/dubbo/qos/command/impl/Offline.java | 23 +++---
 .../org/apache/dubbo/qos/command/impl/Online.java  | 24 +++---
 .../apache/dubbo/rpc/model/ServiceMetadata.java    | 42 ++--------
 5 files changed, 129 insertions(+), 64 deletions(-)


[dubbo] 11/12: Merge branch 'merge-3.x'

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo.git

commit 1090348566dd5afd1f5a03477ccc3120167bd639
Merge: cea3de7 e826d08
Author: ken.lj <ke...@gmail.com>
AuthorDate: Thu Oct 31 16:33:21 2019 +0800

    Merge branch 'merge-3.x'
    
    # Conflicts:
    #	dubbo-common/src/main/java/org/apache/dubbo/common/URL.java
    #	dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ServiceMetadata.java
    #	dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Offline.java
    #	dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Online.java
    #	dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/LsTest.java
    #	dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/OfflineTest.java
    #	dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/OnlineTest.java
    #	dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcInvocation.java
    #	dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java

 .../org/apache/dubbo/common/ServiceDescriptor.java | 94 ++++++++++++++++++++++
 .../src/main/java/org/apache/dubbo/common/URL.java | 16 +---
 .../common/config/OrderedPropertiesProvider.java   |  5 ++
 .../dubbo/common/extension/ExtensionLoader.java    | 39 +++++----
 .../apache/dubbo/rpc/model/ServiceMetadata.java    | 45 ++---------
 .../dubbo/qos/command/impl/TestInterface.java      |  9 +++
 .../dubbo/qos/command/impl/TestInterface2.java     |  9 +++
 .../main/java/org/apache/dubbo/rpc/Invocation.java | 12 +++
 .../org/apache/dubbo/rpc/support/RpcUtils.java     |  3 +
 9 files changed, 166 insertions(+), 66 deletions(-)

diff --cc dubbo-common/src/main/java/org/apache/dubbo/common/URL.java
index b6429d6,6a34fdd..cbe358c
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java
@@@ -407,30 -339,6 +407,18 @@@ class URL implements Serializable 
          }
      }
  
 +    static String appendDefaultPort(String address, int defaultPort) {
 +        if (address != null && address.length() > 0 && defaultPort > 0) {
 +            int i = address.indexOf(':');
 +            if (i < 0) {
 +                return address + ":" + defaultPort;
 +            } else if (Integer.parseInt(address.substring(i + 1)) == 0) {
 +                return address.substring(0, i + 1) + defaultPort;
 +            }
 +        }
 +        return address;
 +    }
 +
-     public static String buildKey(String path, String group, String version) {
-         StringBuilder buf = new StringBuilder();
-         if (group != null && group.length() > 0) {
-             buf.append(group).append("/");
-         }
-         buf.append(path);
-         if (version != null && version.length() > 0) {
-             buf.append(":").append(version);
-         }
-         return buf.toString();
-     }
- 
      public String getProtocol() {
          return protocol;
      }
diff --cc dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ServiceMetadata.java
index f917ac1,0000000..5275030
mode 100644,000000..100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ServiceMetadata.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ServiceMetadata.java
@@@ -1,137 -1,0 +1,102 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one or more
 + * contributor license agreements.  See the NOTICE file distributed with
 + * this work for additional information regarding copyright ownership.
 + * The ASF licenses this file to You 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 org.apache.dubbo.rpc.model;
 +
- import org.apache.dubbo.common.utils.StringUtils;
++import org.apache.dubbo.common.ServiceDescriptor;
++import org.apache.dubbo.common.URL;
 +
 +import java.util.Map;
 +import java.util.concurrent.ConcurrentHashMap;
 +
 +/**
 + * Notice, this class currently has no usage inside Dubbo.
 + *
 + * data related to service level such as name, version, classloader of business service,
 + * security info, etc. Also with a AttributeMap for extension.
 + */
- public class ServiceMetadata {
++public class ServiceMetadata extends ServiceDescriptor {
 +
-     private String serviceKey;
-     private String serviceInterfaceName;
 +    private String defaultGroup;
-     private String version;
 +    private Class<?> serviceType;
 +
-     private volatile String group;
- 
 +    private Object target;
 +
 +    /* will be transferred to remote side */
 +    private final Map<String, Object> attachments = new ConcurrentHashMap<String, Object>();
 +    /* used locally*/
 +    private final Map<String, Object> attributeMap = new ConcurrentHashMap<String, Object>();
 +
 +    public ServiceMetadata(String serviceInterfaceName, String group, String version, Class<?> serviceType) {
 +        this.serviceInterfaceName = serviceInterfaceName;
 +        this.defaultGroup = group;
 +        this.group = group;
 +        this.version = version;
-         this.serviceKey = serviceInterfaceName + ":" + version;
++        this.serviceKey = URL.buildKey(serviceInterfaceName, group, version);
 +        this.serviceType = serviceType;
 +    }
 +
 +    public ServiceMetadata() {
 +    }
 +
 +    public String getServiceKey() {
-         if (StringUtils.isNotEmpty(serviceKey)) {
-             return serviceKey;
-         }
-         return serviceInterfaceName + ":" + version;
++        return serviceKey;
 +    }
 +
 +    public Map<String, Object> getAttachments() {
 +        return attachments;
 +    }
 +
 +    public Map<String, Object> getAttributeMap() {
 +        return attributeMap;
 +    }
 +
 +    public Object getAttribute(String key) {
 +        return attributeMap.get(key);
 +    }
 +
 +    public void addAttribute(String key, Object value) {
 +        this.attributeMap.put(key, value);
 +    }
 +
 +    public void addAttachment(String key, Object value) {
 +        this.attributeMap.put(key, value);
 +    }
 +
 +    public Class<?> getServiceType() {
 +        return serviceType;
 +    }
 +
-     public String getServiceInterfaceName() {
-         return serviceInterfaceName;
-     }
- 
 +    public String getDefaultGroup() {
 +        return defaultGroup;
 +    }
 +
-     public String getVersion() {
-         return version;
-     }
- 
-     public String getGroup() {
-         return group;
-     }
- 
-     public void setGroup(String group) {
-         this.group = group;
-     }
- 
-     public void setServiceInterfaceName(String serviceInterfaceName) {
-         this.serviceInterfaceName = serviceInterfaceName;
-     }
- 
 +    public void setDefaultGroup(String defaultGroup) {
 +        this.defaultGroup = defaultGroup;
 +    }
 +
-     public void setVersion(String version) {
-         this.version = version;
-     }
- 
 +    public void setServiceType(Class<?> serviceType) {
 +        this.serviceType = serviceType;
 +    }
 +
-     public void setServiceKey(String serviceKey) {
-         this.serviceKey = serviceKey;
-     }
- 
 +    public Object getTarget() {
 +        return target;
 +    }
 +
 +    public void setTarget(Object target) {
 +        this.target = target;
 +    }
 +}


[dubbo] 06/12: ExtensionLoader load META-INF/dubbo/internal/ extension from ExtensionLoader ClassLoader first

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo.git

commit fe2b1274d07454a32d2399f084cd50cf0e76d625
Author: hengyunabc <he...@gmail.com>
AuthorDate: Mon Oct 14 18:07:25 2019 +0800

    ExtensionLoader load META-INF/dubbo/internal/ extension from ExtensionLoader ClassLoader first
---
 .../apache/dubbo/common/extension/ExtensionLoader.java | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java
index bc4739d..2f77ee3 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java
@@ -628,8 +628,10 @@ public class ExtensionLoader<T> {
         cacheDefaultExtensionName();
 
         Map<String, Class<?>> extensionClasses = new HashMap<>();
-        loadDirectory(extensionClasses, DUBBO_INTERNAL_DIRECTORY, type.getName());
-        loadDirectory(extensionClasses, DUBBO_INTERNAL_DIRECTORY, type.getName().replace("org.apache", "com.alibaba"));
+        // internal extension load from ExtensionLoader's ClassLoader first
+        loadDirectory(extensionClasses, DUBBO_INTERNAL_DIRECTORY, type.getName(), true);
+        loadDirectory(extensionClasses, DUBBO_INTERNAL_DIRECTORY, type.getName().replace("org.apache", "com.alibaba"), true);
+
         loadDirectory(extensionClasses, DUBBO_DIRECTORY, type.getName());
         loadDirectory(extensionClasses, DUBBO_DIRECTORY, type.getName().replace("org.apache", "com.alibaba"));
         loadDirectory(extensionClasses, SERVICES_DIRECTORY, type.getName());
@@ -658,15 +660,21 @@ public class ExtensionLoader<T> {
     }
 
     private void loadDirectory(Map<String, Class<?>> extensionClasses, String dir, String type) {
+        loadDirectory(extensionClasses, dir, type, false);
+    }
+
+    private void loadDirectory(Map<String, Class<?>> extensionClasses, String dir, String type, boolean extensionLoaderClassLoaderFirst) {
         String fileName = dir + type;
         try {
             Enumeration<java.net.URL> urls = null;
             ClassLoader classLoader = findClassLoader();
             
             // try to load from ExtensionLoader's ClassLoader first
-            ClassLoader extensionLoaderClassLoader = ExtensionLoader.class.getClassLoader();
-            if (ClassLoader.getSystemClassLoader() != extensionLoaderClassLoader) {
-                urls = extensionLoaderClassLoader.getResources(fileName);
+            if (extensionLoaderClassLoaderFirst) {
+                ClassLoader extensionLoaderClassLoader = ExtensionLoader.class.getClassLoader();
+                if (ClassLoader.getSystemClassLoader() != extensionLoaderClassLoader) {
+                    urls = extensionLoaderClassLoader.getResources(fileName);
+                }
             }
             
             if(urls == null || !urls.hasMoreElements()) {