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

Reply via email to