This is an automated email from the ASF dual-hosted git repository. udo pushed a commit to branch feature/GEODE-8067 in repository https://gitbox.apache.org/repos/asf/geode.git
commit a8520812601e707b42abc482819272240307403b Author: Patrick Johnson <pjohn...@pivotal.io> AuthorDate: Fri May 22 13:16:08 2020 -0700 GEODE-8148 - Implement unloadModule. (#5151) --- .../geode/services/module/ModuleService.java | 2 + geode-modules/build.gradle | 1 + .../services/module/impl/GeodeModuleLoader.java | 8 ++ .../module/impl/JBossModuleServiceImpl.java | 14 +++ .../module/impl/JBossModuleServiceImplTest.java | 125 +++++++++++++++++++++ .../module3/java/org/apache/geode/Module3.java | 6 +- .../META-INF/services/org.apache.geode.TestService | 1 + 7 files changed, 156 insertions(+), 1 deletion(-) diff --git a/geode-common-services/src/main/java/org/apache/geode/services/module/ModuleService.java b/geode-common-services/src/main/java/org/apache/geode/services/module/ModuleService.java index 81361be..436398d 100644 --- a/geode-common-services/src/main/java/org/apache/geode/services/module/ModuleService.java +++ b/geode-common-services/src/main/java/org/apache/geode/services/module/ModuleService.java @@ -38,6 +38,8 @@ public interface ModuleService { /** * Unloads a previously loaded module. + * unloadModule does not check for dependent modules, therefor you may only use it to unload + * modules that are not dependencies of other modules. * * @param moduleName name of the module to be unloaded. * @return true on success, false if the module could not be unloaded. diff --git a/geode-modules/build.gradle b/geode-modules/build.gradle index 17572a8..7fa6b14 100644 --- a/geode-modules/build.gradle +++ b/geode-modules/build.gradle @@ -97,4 +97,5 @@ dependencies { module1Compile(sourceSets.test.output) module2Compile(sourceSets.test.output) + module3Compile(sourceSets.test.output) } diff --git a/geode-modules/src/main/java/org/apache/geode/services/module/impl/GeodeModuleLoader.java b/geode-modules/src/main/java/org/apache/geode/services/module/impl/GeodeModuleLoader.java index a9d65c9..df06614 100644 --- a/geode-modules/src/main/java/org/apache/geode/services/module/impl/GeodeModuleLoader.java +++ b/geode-modules/src/main/java/org/apache/geode/services/module/impl/GeodeModuleLoader.java @@ -41,6 +41,14 @@ public class GeodeModuleLoader extends DelegatingModuleLoader { moduleSpecs.put(moduleSpec.getName(), moduleSpec); } + public boolean unloadModule(Module module) { + if (module != null && unloadModuleLocal(module.getName(), module)) { + moduleSpecs.remove(module.getName()); + return true; + } + return false; + } + @Override protected ModuleSpec findModule(String name) throws ModuleLoadException { ModuleSpec moduleSpec = moduleSpecs.get(name); diff --git a/geode-modules/src/main/java/org/apache/geode/services/module/impl/JBossModuleServiceImpl.java b/geode-modules/src/main/java/org/apache/geode/services/module/impl/JBossModuleServiceImpl.java index c7be4c5..14a088a 100644 --- a/geode-modules/src/main/java/org/apache/geode/services/module/impl/JBossModuleServiceImpl.java +++ b/geode-modules/src/main/java/org/apache/geode/services/module/impl/JBossModuleServiceImpl.java @@ -130,6 +130,20 @@ public class JBossModuleServiceImpl implements ModuleService { @Override public boolean unloadModule(String moduleName) { + logger.debug(String.format("Unloading module %s", moduleName)); + if (!modules.containsKey(moduleName)) { + logger.warn( + String.format("Module %s could not be unloaded because it is not loaded", moduleName)); + return false; + } + + if (moduleLoader.unloadModule(modules.get(moduleName))) { + modules.remove(moduleName); + logger.debug(String.format("Module %s was successfully unloaded", moduleName)); + return true; + } + + logger.debug(String.format("Module %s could not be unloaded", moduleName)); return false; } diff --git a/geode-modules/src/test/java/org/apache/geode/services/module/impl/JBossModuleServiceImplTest.java b/geode-modules/src/test/java/org/apache/geode/services/module/impl/JBossModuleServiceImplTest.java index 38bf0b3..be14780 100644 --- a/geode-modules/src/test/java/org/apache/geode/services/module/impl/JBossModuleServiceImplTest.java +++ b/geode-modules/src/test/java/org/apache/geode/services/module/impl/JBossModuleServiceImplTest.java @@ -488,4 +488,129 @@ public class JBossModuleServiceImplTest { assertThat(serviceList.size()).isEqualTo(1); assertThat(serviceList.get(0).sayHello()).isEqualTo(MODULE1_MESSAGE); } + + @Test + public void unloadModule() { + ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0") + .fromSources(MODULE1_PATH) + .build(); + moduleService.loadModule(module1Descriptor); + assertThat(moduleService.unloadModule(module1Descriptor.getVersionedName())).isTrue(); + + assertThat(moduleService.getModule(module1Descriptor.getVersionedName())).isNull(); + + assertThat(moduleService.loadService(TestService.class)).isEmpty(); + } + + @Test + public void unloadModuleFromMultipleJars() { + ModuleDescriptor moduleDescriptor = new ModuleDescriptor.Builder("module1", "1.0") + .fromSources(MODULE1_PATH, MODULE2_PATH) + .build(); + moduleService.loadModule(moduleDescriptor); + assertThat(moduleService.unloadModule(moduleDescriptor.getVersionedName())).isTrue(); + + assertThat(moduleService.getModule(moduleDescriptor.getVersionedName())).isNull(); + + assertThat(moduleService.loadService(TestService.class)).isEmpty(); + } + + @Test + public void unloadOneOfMultipleModules() throws ClassNotFoundException { + ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0") + .fromSources(MODULE1_PATH) + .build(); + moduleService.loadModule(module1Descriptor); + ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module2", "1.0") + .fromSources(MODULE2_PATH) + .build(); + moduleService.loadModule(module2Descriptor); + + assertThat(moduleService.unloadModule(module1Descriptor.getVersionedName())).isTrue(); + + assertThat(moduleService.getModule(module1Descriptor.getVersionedName())).isNull(); + + moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader() + .loadClass("org.apache.geode.Module2"); + + assertThat(moduleService.loadService(TestService.class).size()).isEqualTo(1); + } + + @Test + public void unloadInvalidModuleName() { + assertThat(moduleService.unloadModule("invalidModuleName")).isFalse(); + } + + @Test + public void reloadUnloadedModule() throws ClassNotFoundException { + ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0") + .fromSources(MODULE1_PATH) + .build(); + moduleService.loadModule(module1Descriptor); + assertThat(moduleService.unloadModule(module1Descriptor.getVersionedName())).isTrue(); + + assertThat(moduleService.getModule(module1Descriptor.getVersionedName())).isNull(); + + assertThat(moduleService.loadModule(module1Descriptor)).isTrue(); + moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader() + .loadClass("org.apache.geode.Module1"); + + assertThat(moduleService.loadService(TestService.class).size()).isEqualTo(1); + } + + @Test + public void unloadModuleWithDependencies() throws ClassNotFoundException { + ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0") + .fromSources(MODULE1_PATH) + .build(); + moduleService.loadModule(module1Descriptor); + ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module2", "1.0") + .fromSources(MODULE2_PATH) + .dependsOnModules(module1Descriptor.getVersionedName()) + .build(); + moduleService.loadModule(module2Descriptor); + + assertThat(moduleService.unloadModule(module2Descriptor.getVersionedName())).isTrue(); + + assertThat(moduleService.getModule(module2Descriptor.getVersionedName())).isNull(); + + moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader() + .loadClass("org.apache.geode.Module1"); + + assertThat(moduleService.loadService(TestService.class).size()).isEqualTo(1); + } + + @Test + public void unloadModuleTwice() { + ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0") + .fromSources(MODULE1_PATH) + .build(); + moduleService.loadModule(module1Descriptor); + + assertThat(moduleService.unloadModule(module1Descriptor.getVersionedName())).isTrue(); + + assertThat(moduleService.unloadModule(module1Descriptor.getVersionedName())).isFalse(); + + assertThat(moduleService.getModule(module1Descriptor.getVersionedName())).isNull(); + } + + @Test + public void unloadModuleWithSourceSharedByOtherModule() throws ClassNotFoundException { + ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0") + .fromSources(MODULE1_PATH, MODULE2_PATH) + .build(); + moduleService.loadModule(module1Descriptor); + ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module2", "1.0") + .fromSources(MODULE2_PATH, MODULE3_PATH) + .build(); + moduleService.loadModule(module2Descriptor); + assertThat(moduleService.unloadModule(module1Descriptor.getVersionedName())).isTrue(); + + moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader() + .loadClass("org.apache.geode.Module2"); + moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader() + .loadClass("org.apache.geode.Module3"); + + assertThat(moduleService.loadService(TestService.class).size()).isEqualTo(2); + } } diff --git a/geode-modules/src/testModules/module3/java/org/apache/geode/Module3.java b/geode-modules/src/testModules/module3/java/org/apache/geode/Module3.java index 87035eb..34bfbdd 100644 --- a/geode-modules/src/testModules/module3/java/org/apache/geode/Module3.java +++ b/geode-modules/src/testModules/module3/java/org/apache/geode/Module3.java @@ -15,5 +15,9 @@ package org.apache.geode; -public class Module3 { +public class Module3 implements TestService { + @Override + public String sayHello() { + return "Hello from Module3!"; + } } diff --git a/geode-modules/src/testModules/module3/resources/META-INF/services/org.apache.geode.TestService b/geode-modules/src/testModules/module3/resources/META-INF/services/org.apache.geode.TestService new file mode 100644 index 0000000..e47bd26 --- /dev/null +++ b/geode-modules/src/testModules/module3/resources/META-INF/services/org.apache.geode.TestService @@ -0,0 +1 @@ +org.apache.geode.Module3 \ No newline at end of file