You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by al...@apache.org on 2021/09/20 16:23:56 UTC

[dubbo] branch 3.0 updated: [3.0] fix destroy IllegalStateException and doOverrideIfNecessary NPE (#8768)

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

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


The following commit(s) were added to refs/heads/3.0 by this push:
     new 22dc294  [3.0] fix destroy IllegalStateException and doOverrideIfNecessary NPE (#8768)
22dc294 is described below

commit 22dc29472c8919ba7c5d853c65600be106560519
Author: zrlw <zr...@sina.com>
AuthorDate: Tue Sep 21 00:23:46 2021 +0800

    [3.0] fix destroy IllegalStateException and doOverrideIfNecessary NPE (#8768)
    
    * fix destroy IllegalState and doOverrideIfNecessary potential NPE
    
    * add ut and fix NPE
    
    * add UT
    
    * fix ut
---
 .../apache/dubbo/rpc/model/ApplicationModel.java   |  6 +++
 .../apache/dubbo/config/ReferenceConfigTest.java   | 51 ++++++++++++++++++++++
 .../registry/integration/RegistryProtocol.java     | 12 +++--
 3 files changed, 66 insertions(+), 3 deletions(-)

diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java
index 7d14388..932dc6d 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java
@@ -32,6 +32,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
+import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -275,6 +276,11 @@ public class ApplicationModel extends ScopeModel {
         return getCurrentConfig().getName();
     }
 
+    public String tryGetApplicationName() {
+        Optional<ApplicationConfig> appCfgOptional = getApplicationConfigManager().getApplication();
+        return appCfgOptional.isPresent() ? appCfgOptional.get().getName() : null;
+    }
+
     void addModule(ModuleModel moduleModel, boolean isInternal) {
         synchronized (moduleLock) {
             if (!this.moduleModels.contains(moduleModel)) {
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
index f75aa8a..2580cf3 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
@@ -734,6 +734,57 @@ public class ReferenceConfigTest {
     }
 
     @Test
+    public void test2ReferenceRetry() {
+        ApplicationConfig application = new ApplicationConfig();
+        application.setName("test-reference-retry2");
+        application.setEnableFileCache(false);
+        ApplicationModel.defaultModel().getApplicationConfigManager().setApplication(application);
+
+        RegistryConfig registry = new RegistryConfig();
+        registry.setAddress(zkUrl1);
+        ProtocolConfig protocol = new ProtocolConfig();
+        protocol.setName("mockprotocol");
+
+        ReferenceConfig<DemoService> rc = new ReferenceConfig<>();
+        rc.setRegistry(registry);
+        rc.setInterface(DemoService.class.getName());
+
+        boolean success = false;
+        DemoService demoService = null;
+        try {
+            demoService = rc.get();
+            success = true;
+        } catch (Exception e) {
+            // ignore
+        }
+        Assertions.assertFalse(success);
+        Assertions.assertNull(demoService);
+
+        ServiceConfig<DemoService> sc = new ServiceConfig<>();
+        sc.setInterface(DemoService.class.getName());
+        sc.setRef(new DemoServiceImpl());
+        sc.setRegistry(registry);
+        sc.setProtocol(protocol);
+
+        try {
+            System.setProperty("java.net.preferIPv4Stack", "true");
+            sc.export();
+            demoService = rc.get();
+            success = true;
+        } catch (Exception e) {
+            // ignore
+        } finally {
+            rc.destroy();
+            sc.unexport();
+            System.clearProperty("java.net.preferIPv4Stack");
+
+        }
+        Assertions.assertTrue(success);
+        Assertions.assertNotNull(demoService);
+
+    }
+
+    @Test
     public void testMetaData() {
         ReferenceConfig config = new ReferenceConfig();
         Map<String, String> metaData = config.getMetaData();
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java
index dbcd8ac..404c679 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java
@@ -604,9 +604,14 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
         for (ApplicationModel applicationModel : frameworkModel.getApplicationModels()) {
             if (applicationModel.getModelEnvironment().getConfiguration().convert(Boolean.class, org.apache.dubbo.registry.Constants.ENABLE_CONFIGURATION_LISTEN, true)) {
                 for (ModuleModel moduleModel : applicationModel.getPubModuleModels()) {
+                    String applicationName = applicationModel.tryGetApplicationName();
+                    if (applicationName == null) {
+                        // already removed
+                        continue;
+                    }
                     if (moduleModel.getServiceRepository().getExportedServices().size() > 0) {
                         moduleModel.getExtensionLoader(GovernanceRuleRepository.class).getDefaultExtension()
-                            .removeListener(applicationModel.getApplicationName() + CONFIGURATORS_SUFFIX,
+                            .removeListener(applicationName + CONFIGURATORS_SUFFIX,
                                 getProviderConfigurationListener(moduleModel));
                     }
                 }
@@ -732,13 +737,14 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
                 return;
             }
             //The current, may have been merged many times
-            URL currentUrl = exporter.getInvoker().getUrl();
+            Invoker<?> exporterInvoker = exporter.getInvoker();
+            URL currentUrl = exporterInvoker == null ? null : exporterInvoker.getUrl();
             //Merged with this configuration
             URL newUrl = getConfiguredInvokerUrl(configurators, originUrl);
             newUrl = getConfiguredInvokerUrl(getProviderConfigurationListener(originUrl).getConfigurators(), newUrl);
             newUrl = getConfiguredInvokerUrl(serviceConfigurationListeners.get(originUrl.getServiceKey())
                 .getConfigurators(), newUrl);
-            if (!currentUrl.equals(newUrl)) {
+            if (!newUrl.equals(currentUrl)) {
                 if (newUrl.getParameter(Constants.NEED_REEXPORT, true)) {
                     RegistryProtocol.this.reExport(originInvoker, newUrl);
                 }