Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.0] fix destroy IllegalStateException and doOverrideIfNecessary NPE #8768

Merged
merged 11 commits into from
Sep 20, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
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;

Expand Down Expand Up @@ -275,6 +276,11 @@ public String getApplicationName() {
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)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,57 @@ public void test1ReferenceRetry() {

}

@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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -604,9 +604,14 @@ public void destroy() {
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));
}
}
Expand Down Expand Up @@ -732,13 +737,14 @@ public synchronized void doOverrideIfNecessary() {
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);
}
Expand Down