You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ud...@apache.org on 2020/07/08 19:35:33 UTC

[geode] branch feature/GEODE-8067 updated (0f2e014 -> 23babb8)

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

udo pushed a change to branch feature/GEODE-8067
in repository https://gitbox.apache.org/repos/asf/geode.git.


 discard 0f2e014  GEODE-8239 - Add gradle config to add 'Class-Path' and 'Dependent-Modules' attirbutes to manifest file. (#5297)
 discard d43fbde  GEODE-8190: Clean up tests and automate Geode version. (#5243) (#5293)
 discard 29fb317  GEODE-8190 - Completed GeodeJarModuleFinder to register and load Modules. (#5234)
 discard 16f5eed  GEODE-8148 - Implement unloadModule. (#5151)
 discard 5ada3e1  GEODE-8137 - Implement loadService. (#5136)
 discard 4f60107  GEODE-8043 - Create JBossModuleService and implement loadModule. (#5081)
 discard d99d256  GEODE-8041 - Create ManagementService interface. (#5062)
 discard d5a337b  GEODE-8037 - Create BootstrappingService interface. (#5046)
     add 868d4bc  GEODE-8330: Structural Improvements to Versioning
     add 13d17ec  GEODE-8313: Improve RedisData synchronization for toData (#5318)
     add 9d7d467  GEODE-8341: Correct docs typo in gfsh export logs (#5352)
     new 82e1405  GEODE-8037 - Create BootstrappingService interface. (#5046)
     new 36d519b  GEODE-8041 - Create ManagementService interface. (#5062)
     new 700f9d4  GEODE-8043 - Create JBossModuleService and implement loadModule. (#5081)
     new 979bb4e  GEODE-8137 - Implement loadService. (#5136)
     new 73c519a  GEODE-8148 - Implement unloadModule. (#5151)
     new 5f7b60a  GEODE-8190 - Completed GeodeJarModuleFinder to register and load Modules. (#5234)
     new 627304a  GEODE-8190: Clean up tests and automate Geode version. (#5243) (#5293)
     new 23babb8  GEODE-8239 - Add gradle config to add 'Class-Path' and 'Dependent-Modules' attirbutes to manifest file. (#5297)

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (0f2e014)
            \
             N -- N -- N   refs/heads/feature/GEODE-8067 (23babb8)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 8 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:
 .../codeAnalysis/sanctionedDataSerializables.txt   |   2 +-
 .../client/internal/ClientSideHandshakeImpl.java   |  21 +-
 .../distributed/internal/ReplyProcessor21.java     |  16 +-
 .../membership/InternalDistributedMember.java      |  13 -
 .../internal/streaming/StreamingOperation.java     |   4 +-
 .../apache/geode/internal/cache/DiskInitFile.java  |   3 +-
 .../internal/cache/InitialImageOperation.java      |   9 +-
 .../org/apache/geode/internal/cache/Oplog.java     |  25 +-
 .../geode/internal/cache/ha/HARegionQueue.java     |   5 +-
 .../cache/partitioned/FetchBulkEntriesMessage.java |   4 +-
 .../cache/partitioned/FetchEntriesMessage.java     |   4 +-
 .../cache/partitioned/FetchKeysMessage.java        |   4 +-
 .../partitioned/StreamingPartitionOperation.java   |   5 +-
 .../cache/persistence/DiskInitFileParser.java      |  13 +-
 .../tier/sockets/ClientProxyMembershipID.java      |   6 +-
 .../tier/sockets/ClientRegistrationMetadata.java   |  69 +++--
 .../cache/tier/sockets/ServerConnection.java       |   2 +-
 .../tier/sockets/ServerSideHandshakeFactory.java   |  48 ++--
 .../tier/sockets/ServerSideHandshakeImpl.java      |   3 +-
 .../internal/cache/tx/RemoteFetchKeysMessage.java  |   5 +-
 .../org/apache/geode/internal/tcp/Connection.java  |  14 +-
 .../configuration/domain/Configuration.java        |   5 +-
 .../gfsh/command-pages/export.html.md.erb          |   2 +-
 .../LuceneSearchWithRollingUpgradeTestBase.java    |  13 +-
 .../internal/membership/gms/GMSMemberData.java     |   8 +-
 .../membership/gms/MemberIdentifierImpl.java       |   7 +-
 .../membership/gms/locator/GMSLocator.java         |   6 +-
 .../membership/gms/messenger/JGroupsMessenger.java |  36 ++-
 geode-redis/build.gradle                           |   1 +
 .../executor/hash/HashesAndCrashesDUnitTest.java   | 314 +++++++++++++++++++++
 .../config/DUnitSocketAddressResolver.java         |   6 +
 .../geode/redis/internal/data/RedisHash.java       |  47 ++-
 .../apache/geode/redis/internal/data/RedisSet.java |  36 ++-
 .../geode/redis/internal/data/RedisString.java     |   9 +
 .../internal/executor/key/RenameFunction.java      |   6 +
 ...ersionOrdinalImpl.java => AbstractVersion.java} |  54 ++--
 .../internal/serialization/UnknownVersion.java     |  13 +-
 .../geode/internal/serialization/Version.java      | 213 ++------------
 .../internal/serialization/VersionOrdinal.java     |   2 +-
 .../geode/internal/serialization/Versioning.java   |  37 ++-
 .../geode/internal/serialization/VersioningIO.java | 112 ++++++++
 ...JUnitTest.java => UnknownVersionJUnitTest.java} |  34 ++-
 .../internal/serialization/VersionJUnitTest.java   |  24 +-
 .../serialization/VersioningJUnitTest.java         |  73 +++++
 .../distributed/internal/tcpserver/TcpClient.java  |  39 +--
 .../distributed/internal/tcpserver/TcpServer.java  |  20 +-
 .../RemoteParallelGatewaySenderEventProcessor.java |   3 +-
 47 files changed, 945 insertions(+), 450 deletions(-)
 create mode 100644 geode-redis/src/distributedTest/java/org/apache/geode/redis/internal/executor/hash/HashesAndCrashesDUnitTest.java
 rename geode-serialization/src/main/java/org/apache/geode/internal/serialization/{VersionOrdinalImpl.java => AbstractVersion.java} (72%)
 copy geode-core/src/main/java/org/apache/geode/internal/size/SingleObjectSizer.java => geode-serialization/src/main/java/org/apache/geode/internal/serialization/UnknownVersion.java (76%)
 create mode 100644 geode-serialization/src/main/java/org/apache/geode/internal/serialization/VersioningIO.java
 rename geode-serialization/src/test/java/org/apache/geode/internal/serialization/{VersionOrdinalImplJUnitTest.java => UnknownVersionJUnitTest.java} (74%)
 create mode 100644 geode-serialization/src/test/java/org/apache/geode/internal/serialization/VersioningJUnitTest.java


[geode] 06/08: GEODE-8190 - Completed GeodeJarModuleFinder to register and load Modules. (#5234)

Posted by ud...@apache.org.
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 5f7b60ae766473b902166fda226262b828c8fe8d
Author: Patrick Johnson <pj...@pivotal.io>
AuthorDate: Wed Jun 10 19:51:34 2020 -0700

    GEODE-8190 - Completed GeodeJarModuleFinder to register and load Modules. (#5234)
    
    JBossModuleServiceImpl can now register and load Modules using ModuleDescriptor. The ModuleDescriptor
    can now contain source paths to be included in the module as code sources or
    have dependencies on other modules.
    
    The same functionality can now be represented/retrieved from the Manifest file
    contained within the jar files.
    
    Amended gradle scripts for geode-common-services and geode-common to now generate
    manifest files containing "Class-Path" dependencies and project module dependencies
    described in the "Dependent-Modules" attribute in the manifest file.
---
 .../integrationTest/resources/assembly_content.txt |  11 +-
 geode-common-services/build.gradle                 |  38 +-
 .../services/management/ManagementService.java     |   5 +-
 .../geode/services/module/ModuleDescriptor.java    |  93 ++-
 .../geode/services/module/ModuleService.java       |  86 ++-
 .../ModuleServiceResult.java}                      |  39 +-
 .../org/apache/geode/services/result/Result.java   |  87 +++
 .../src/test/resources/expected-pom.xml            |  10 +-
 geode-common/build.gradle                          |  37 +
 geode-modules/build.gradle                         | 174 +++--
 .../services/module/impl/GeodeModuleLoader.java    |  61 --
 .../module/impl/JBossModuleServiceImpl.java        | 270 ++++---
 .../internal/finder/DelegatingModuleFinder.java    |  67 ++
 .../module/internal/loader/GeodeModuleLoader.java  | 129 ++++
 .../apache/geode/services/result/impl/Failure.java |  90 +++
 .../apache/geode/services/result/impl/Success.java |  91 +++
 .../org/jboss/modules/GeodeJarModuleFinder.java    | 293 ++++++++
 .../module/impl/JBossModuleServiceImplTest.java    | 616 ----------------
 ...erviceImplWithoutPopulatedManifestFileTest.java | 819 +++++++++++++++++++++
 ...esServiceImplWithPopulatedManifestFileTest.java | 144 ++++
 .../jboss/modules/GeodeJarModuleFinderTest.java    | 231 ++++++
 geode-modules/src/test/resources/expected-pom.xml  |  28 +-
 .../META-INF/services/org.apache.geode.TestService |   1 -
 .../java/org/apache/geode/ModuleService1.java}     |   2 +-
 .../META-INF/services/org.apache.geode.TestService |   1 +
 .../java/org/apache/geode/ModuleService1.java}     |   2 +-
 .../META-INF/services/org.apache.geode.TestService |   1 +
 .../META-INF/services/org.apache.geode.TestService |   1 -
 .../java/org/apache/geode/ModuleService2.java}     |   2 +-
 .../META-INF/services/org.apache.geode.TestService |   1 +
 .../java/org/apache/geode/ModuleService2.java}     |   2 +-
 .../META-INF/services/org.apache.geode.TestService |   1 +
 .../META-INF/services/org.apache.geode.TestService |   1 -
 .../java/org/apache/geode/ModuleService3.java}     |   2 +-
 .../META-INF/services/org.apache.geode.TestService |   1 +
 .../java/org/apache/geode/ModuleService3.java}     |   2 +-
 .../META-INF/services/org.apache.geode.TestService |   1 +
 .../java/org/apache/geode/ModuleService4.java}     |   2 +-
 .../java/org/apache/geode/ModuleService4.java}     |   2 +-
 .../java/org/apache/geode/ModuleService5.java}     |   2 +-
 40 files changed, 2510 insertions(+), 936 deletions(-)

diff --git a/geode-assembly/src/integrationTest/resources/assembly_content.txt b/geode-assembly/src/integrationTest/resources/assembly_content.txt
index 3e21fb9..cc2d508 100644
--- a/geode-assembly/src/integrationTest/resources/assembly_content.txt
+++ b/geode-assembly/src/integrationTest/resources/assembly_content.txt
@@ -977,7 +977,6 @@ javadoc/org/apache/geode/services/management/package-tree.html
 javadoc/org/apache/geode/services/module/ModuleDescriptor.Builder.html
 javadoc/org/apache/geode/services/module/ModuleDescriptor.html
 javadoc/org/apache/geode/services/module/ModuleService.html
-javadoc/org/apache/geode/services/module/impl/GeodeModuleLoader.html
 javadoc/org/apache/geode/services/module/impl/JBossModuleServiceImpl.html
 javadoc/org/apache/geode/services/module/impl/package-frame.html
 javadoc/org/apache/geode/services/module/impl/package-summary.html
@@ -985,6 +984,16 @@ javadoc/org/apache/geode/services/module/impl/package-tree.html
 javadoc/org/apache/geode/services/module/package-frame.html
 javadoc/org/apache/geode/services/module/package-summary.html
 javadoc/org/apache/geode/services/module/package-tree.html
+javadoc/org/apache/geode/services/result/ModuleServiceResult.html
+javadoc/org/apache/geode/services/result/Result.html
+javadoc/org/apache/geode/services/result/impl/Failure.html
+javadoc/org/apache/geode/services/result/impl/Success.html
+javadoc/org/apache/geode/services/result/impl/package-frame.html
+javadoc/org/apache/geode/services/result/impl/package-summary.html
+javadoc/org/apache/geode/services/result/impl/package-tree.html
+javadoc/org/apache/geode/services/result/package-frame.html
+javadoc/org/apache/geode/services/result/package-summary.html
+javadoc/org/apache/geode/services/result/package-tree.html
 javadoc/overview-frame.html
 javadoc/overview-summary.html
 javadoc/overview-tree.html
diff --git a/geode-common-services/build.gradle b/geode-common-services/build.gradle
index da983cf..6225974 100644
--- a/geode-common-services/build.gradle
+++ b/geode-common-services/build.gradle
@@ -27,7 +27,43 @@ repositories {
 dependencies {
     compile(platform(project(':boms:geode-all-bom')))
 
+    compile('org.apache.commons:commons-lang3')
+
     compile(project(':geode-common'))
+}
+
+def geodeProjects = ['geode-common-services', 'geode-common']
+
+jar {
+    doFirst {
+        def projectDependencies = []
+        def runtimeList = []
+
+        configurations.runtimeClasspath
+                .collect { it.name - ".jar" }
+                .each { dependency ->
+                    if (dependency.startsWith("geode-")) {
+                        projectDependencies.add(dependency)
+                    } else {
+                        runtimeList.add(dependency)
+                    }
+                }
 
-    compile(project(':geode-core'))
+        projectDependencies.each { projectDependency ->
+            geodeProjects.each { geodeProject ->
+                if (projectDependency.contains(geodeProject)) {
+                    def parentProject = project(":$geodeProject")
+                    if (parentProject != null) {
+                        def collect = parentProject.configurations.runtimeClasspath.collect { it.name - ".jar" }
+                        runtimeList.removeAll(collect)
+                        projectDependencies.removeAll(collect)
+                    }
+                }
+            }
+        }
+        manifest {
+            attributes("Class-Path": runtimeList.join(' '))
+            attributes("Dependent-Modules": projectDependencies.join(' '))
+        }
+    }
 }
diff --git a/geode-common-services/src/main/java/org/apache/geode/services/management/ManagementService.java b/geode-common-services/src/main/java/org/apache/geode/services/management/ManagementService.java
index 3e9ca47..5ae23c5 100644
--- a/geode-common-services/src/main/java/org/apache/geode/services/management/ManagementService.java
+++ b/geode-common-services/src/main/java/org/apache/geode/services/management/ManagementService.java
@@ -15,10 +15,7 @@
 
 package org.apache.geode.services.management;
 
-import java.util.Properties;
-
 import org.apache.geode.annotations.Experimental;
-import org.apache.geode.cache.Cache;
 
 /**
  * Entry point for creating a cache and bootstrapping Geode using the BootstrappingService
@@ -35,5 +32,5 @@ public interface ManagementService {
    *
    * @throws Exception is Cache cannot be created.
    */
-  Cache createCache(Properties properties) throws Exception;
+  // Cache createCache(Properties properties) throws Exception;
 }
diff --git a/geode-common-services/src/main/java/org/apache/geode/services/module/ModuleDescriptor.java b/geode-common-services/src/main/java/org/apache/geode/services/module/ModuleDescriptor.java
index 3b84130..dc8182d 100644
--- a/geode-common-services/src/main/java/org/apache/geode/services/module/ModuleDescriptor.java
+++ b/geode-common-services/src/main/java/org/apache/geode/services/module/ModuleDescriptor.java
@@ -16,56 +16,70 @@
 package org.apache.geode.services.module;
 
 import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.commons.lang3.StringUtils;
 
 import org.apache.geode.annotations.Experimental;
 
 /**
- * Holds information to describe a classloader-isolated module including how to create it.
+ * Holds configuration information to describe a classloader-isolated module.
  *
  * @see Builder
  * @see ModuleService
- *
- * @since Geode 1.13.0
+ * @since Geode 1.14.0
  */
 @Experimental
 public class ModuleDescriptor {
 
-  private String name;
+  // The name of the module
+  private final String name;
 
-  private String version;
+  // The version module. Maybe be null
+  private final String version;
 
-  private List<String> sources;
+  // A collection of source paths for the module
+  private final Set<String> resourceJarPaths;
 
-  private List<String> dependencies;
+  // A collection of module names on which this module depends on
+  private final Set<String> dependencies;
 
-  private ModuleDescriptor(String name, String version, List<String> sources,
-      List<String> dependencies) {
+  private ModuleDescriptor(String name, String version, Set<String> resourceJarPaths,
+      Set<String> dependencies) {
     this.name = name;
     this.version = version;
-    this.sources = sources;
+    this.resourceJarPaths = resourceJarPaths;
     this.dependencies = dependencies;
   }
 
-  public String getName() {
-    return name;
-  }
-
-  public String getVersion() {
-    return version;
-  }
-
-  public List<String> getSources() {
-    return sources;
+  /**
+   * A collection of resource paths that are to be loaded by the module
+   *
+   * @return a collection of resource paths for the module
+   */
+  public Set<String> getResourceJarPaths() {
+    return resourceJarPaths;
   }
 
-  public List<String> getDependedOnModules() {
+  /**
+   * A collection of module names on which this module is dependent on
+   *
+   * @return A collection of module names on which this module is dependent on
+   */
+  public Set<String> getDependedOnModules() {
     return dependencies;
   }
 
-  public String getVersionedName() {
-    return name + ":" + version;
+  /**
+   * The name of the module concatenated with the version provided. In the case of the version being
+   * null
+   * the name does not contain the version.
+   *
+   */
+  public String getName() {
+    return name + (version != null ? "-" + version : "");
   }
 
   /**
@@ -75,21 +89,38 @@ public class ModuleDescriptor {
 
     private final String name;
     private final String version;
-    private List<String> dependencies = Collections.emptyList();
-    private List<String> sources = Collections.emptyList();
+    private final Set<String> dependencies = new HashSet<>();
+    private final Set<String> sources = new HashSet<>();
+
+    public Builder(String name) {
+      this(name, null);
+    }
 
     public Builder(String name, String version) {
-      this.name = name;
+      if (!StringUtils.isEmpty(name)) {
+        this.name = name;
+      } else {
+        throw new IllegalArgumentException(
+            "Name in the ModuleDescriptor.Builder cannot be null or empty");
+      }
       this.version = version;
     }
 
-    public Builder fromSources(String... sources) {
-      this.sources = Arrays.asList(sources);
+    public Builder fromResourcePaths(String... resourcePaths) {
+      return fromResourcePaths(Arrays.asList(resourcePaths));
+    }
+
+    public Builder fromResourcePaths(Collection<String> resourcePaths) {
+      this.sources.addAll(resourcePaths);
       return this;
     }
 
     public Builder dependsOnModules(String... dependencies) {
-      this.dependencies = Arrays.asList(dependencies);
+      return this.dependsOnModules(Arrays.asList(dependencies));
+    }
+
+    public Builder dependsOnModules(Collection<String> dependencies) {
+      this.dependencies.addAll(dependencies);
       return this;
     }
 
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 436398d..e6c693c 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
@@ -15,14 +15,16 @@
 
 package org.apache.geode.services.module;
 
-import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import org.apache.geode.annotations.Experimental;
+import org.apache.geode.services.result.ModuleServiceResult;
 
 /**
  * Loads and unloads modules and services in a classloader-isolated manner.
  *
- * @since Geode 1.13.0
+ * @since Geode 1.14.0
  */
 @Experimental
 public interface ModuleService {
@@ -32,9 +34,30 @@ public interface ModuleService {
    *
    * @param moduleDescriptor description of the module to be loaded and information necessary to
    *        load it.
-   * @return true on success, false if the module could not be loaded.
+   * @return {@link ModuleServiceResult}. This type represents either Success or Failure. Using
+   *         {@link ModuleServiceResult#isSuccessful()} returns a {@literal Boolean} in the case of
+   *         success.
+   *         Upon success use {@link ModuleServiceResult#getMessage()} to get the result and upon
+   *         failure
+   *         used {@link ModuleServiceResult#getErrorMessage()} to get the error message of the
+   *         failure.
    */
-  boolean loadModule(ModuleDescriptor moduleDescriptor);
+  ModuleServiceResult<Boolean> loadModule(ModuleDescriptor moduleDescriptor);
+
+  /**
+   * Registers a module from the {@link ModuleDescriptor}.
+   *
+   * @param moduleDescriptor description of the module to be loaded and information necessary to
+   *        register it.
+   * @return {@link ModuleServiceResult}. This type represents either Success or Failure. Using
+   *         {@link ModuleServiceResult#isSuccessful()} returns a {@literal Boolean} in the case of
+   *         success.
+   *         Upon success use {@link ModuleServiceResult#getMessage()} to get the result and upon
+   *         failure
+   *         used {@link ModuleServiceResult#getErrorMessage()} to get the error message of the
+   *         failure.
+   */
+  ModuleServiceResult<Boolean> registerModule(ModuleDescriptor moduleDescriptor);
 
   /**
    * Unloads a previously loaded module.
@@ -42,15 +65,60 @@ public interface ModuleService {
    * 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.
+   * @return {@link ModuleServiceResult}. This type represents either Success or Failure. Using
+   *         {@link ModuleServiceResult#isSuccessful()} returns a {@literal Boolean} in the case of
+   *         success.
+   *         Upon success use {@link ModuleServiceResult#getMessage()} to get the result and upon
+   *         failure
+   *         used {@link ModuleServiceResult#getErrorMessage()} to get the error message of the
+   *         failure.
    */
-  boolean unloadModule(String moduleName);
+  ModuleServiceResult<Boolean> unloadModule(String moduleName);
 
   /**
-   * Loads and returns a service instance for an interface.
+   * Loads and returns a service instance from any loaded module.
    *
    * @param service interface type to load and instantiate an implementation of.
-   * @return An instance of an implementation of service
+   * @return {@link ModuleServiceResult}. This type represents either Success or Failure. Using
+   *         {@link ModuleServiceResult#isSuccessful()} returns a {@literal Map<String,Set<T>>} in
+   *         the case of success.
+   *         The result is a Map of {@code <ModuleName,Set<ServiceInstance>>}. Where moduleName
+   *         corresponds
+   *         to the serviceInstance from the module.
+   *         Upon success use {@link ModuleServiceResult#getMessage()} to get the result and upon
+   *         failure
+   *         used {@link ModuleServiceResult#getErrorMessage()} to get the error message of the
+   *         failure.
+   */
+  <T> ModuleServiceResult<Map<String, Set<T>>> loadService(Class<T> service);
+
+  /**
+   * Returns the Class for the provided name for a specific module.
+   *
+   * @param className the classname that is to be loaded
+   * @param moduleDescriptor the ${@link ModuleDescriptor} used to lookup the module in question
+   * @return {@link ModuleServiceResult}. This type represents either Success or Failure. Using
+   *         {@link ModuleServiceResult#isSuccessful()} returns a {@literal Class<T>} in the case of
+   *         success.
+   *         Upon success use {@link ModuleServiceResult#getMessage()} to get the result and upon
+   *         failure
+   *         used {@link ModuleServiceResult#getErrorMessage()} to get the error message of the
+   *         failure.
+   */
+  ModuleServiceResult<Class<?>> loadClass(String className, ModuleDescriptor moduleDescriptor);
+
+  /**
+   * Returns the Class for the provided name for all loaded module.
+   *
+   * @param className the classname that is to be loaded
+   * @return {@link ModuleServiceResult}. This type represents either Success or Failure. Using
+   *         {@link ModuleServiceResult#isSuccessful()} returns a {@literal Map<String,Class<T>>} in
+   *         the case of success.
+   *         The resultant map returns a list of modules where the class can be loaded from.
+   *         Upon success use {@link ModuleServiceResult#getMessage()} to get the result and upon
+   *         failure
+   *         used {@link ModuleServiceResult#getErrorMessage()} to get the error message of the
+   *         failure.
    */
-  <T> List<T> loadService(Class<T> service);
+  ModuleServiceResult<Map<String, Class<?>>> loadClass(String className);
 }
diff --git a/geode-common-services/src/main/java/org/apache/geode/services/management/ManagementService.java b/geode-common-services/src/main/java/org/apache/geode/services/result/ModuleServiceResult.java
similarity index 50%
copy from geode-common-services/src/main/java/org/apache/geode/services/management/ManagementService.java
copy to geode-common-services/src/main/java/org/apache/geode/services/result/ModuleServiceResult.java
index 3e9ca47..f516c44 100644
--- a/geode-common-services/src/main/java/org/apache/geode/services/management/ManagementService.java
+++ b/geode-common-services/src/main/java/org/apache/geode/services/result/ModuleServiceResult.java
@@ -13,27 +13,36 @@
  * the License.
  */
 
-package org.apache.geode.services.management;
+package org.apache.geode.services.result;
 
-import java.util.Properties;
-
-import org.apache.geode.annotations.Experimental;
-import org.apache.geode.cache.Cache;
+import java.util.function.Function;
 
 /**
- * Entry point for creating a cache and bootstrapping Geode using the BootstrappingService
+ * The {@link ModuleServiceResult} type is an attempt at the function construct of
+ * <a href="https://www.vavr.io/vavr-docs/#_either">Either</a>. In this implementation a
+ * {@link ModuleServiceResult}
+ * can define either success or failure (error) using the same type.
+ *
+ * @param <SuccessType> the return type for a successful operation.
  *
- * @since Geode 1.13.0
+ * @since 1.14.0
  */
-@Experimental
-public interface ManagementService {
+public interface ModuleServiceResult<SuccessType> extends Result<SuccessType, String> {
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  <T> T map(Function<SuccessType, T> successFunction, Function<String, T> errorFunction);
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  SuccessType getMessage();
 
   /**
-   * Creates a Geode Cache given some configuration.
-   *
-   * @param properties system properties to use when creating the Cache.
-   *
-   * @throws Exception is Cache cannot be created.
+   * {@inheritDoc}
    */
-  Cache createCache(Properties properties) throws Exception;
+  @Override
+  String getErrorMessage();
 }
diff --git a/geode-common-services/src/main/java/org/apache/geode/services/result/Result.java b/geode-common-services/src/main/java/org/apache/geode/services/result/Result.java
new file mode 100644
index 0000000..b20109c
--- /dev/null
+++ b/geode-common-services/src/main/java/org/apache/geode/services/result/Result.java
@@ -0,0 +1,87 @@
+/*
+ * 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.geode.services.result;
+
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+import org.apache.geode.annotations.Experimental;
+
+/**
+ * The {@link Result} type is an attempt at the function construct of
+ * * <a href="https://www.vavr.io/vavr-docs/#_either">Either</a>. In this implementation a
+ * {@link Result}
+ * * can define either success or failure (error) using the same type.
+ *
+ * @param <SuccessType> the return type in the event of operational success
+ * @param <FailureType> the return type in the event of operational failure
+ */
+@Experimental
+public interface Result<SuccessType, FailureType> {
+  /**
+   * A mapping function that maps to either <SuccessType> or <FailureType> depending on success or
+   * failure of the operation.
+   *
+   * @param successFunction the mapping function to map the SuccessType to the resultant type
+   * @param errorFunction the mapping function to map the FailureType to the resultant error type
+   * @param <T> the resultant type
+   * @return result of type <T>
+   */
+  <T> T map(Function<SuccessType, T> successFunction,
+      Function<FailureType, T> errorFunction);
+
+  /**
+   * The return message of a successful operation. The return type is of type <SuccessType>
+   *
+   * @return the result of the operation
+   */
+  SuccessType getMessage();
+
+  /**
+   * The return message of a failed operation. The return type is of type <FailureType>
+   *
+   * @return the failure message of why the operation did not succeed.
+   */
+  FailureType getErrorMessage();
+
+  /**
+   * Returns a boolean to indicate the success or failure of the operation
+   *
+   * @return {@literal true} or {@literal false} indicating success or failure of the operation
+   */
+  default boolean isSuccessful() {
+    return false;
+  }
+
+  /**
+   * If the result of the operation is successful, invoke the specified consumer with the value,
+   * otherwise do nothing.
+   *
+   * @param consumer block to be executed if a value is present
+   * @throws NullPointerException if value is present and {@code consumer} is
+   *         null
+   */
+  default void ifSuccessful(Consumer<? super SuccessType> consumer) {}
+
+  /**
+   * If the result of the operation has failed, invoke the specified consumer with the value,
+   * otherwise do nothing.
+   *
+   * @param consumer block to be executed if a value is present
+   * @throws NullPointerException if value is present and {@code consumer} is
+   *         null
+   */
+  default void ifFailure(Consumer<? super String> consumer) {}
+}
diff --git a/geode-common-services/src/test/resources/expected-pom.xml b/geode-common-services/src/test/resources/expected-pom.xml
index 26f1cdd..dbc47ae 100644
--- a/geode-common-services/src/test/resources/expected-pom.xml
+++ b/geode-common-services/src/test/resources/expected-pom.xml
@@ -19,7 +19,7 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>org.apache.geode</groupId>
   <artifactId>geode-common-services</artifactId>
-  <version>1.13.0-SNAPSHOT</version>
+  <version>${version}</version>
   <name>Apache Geode</name>
   <description>Apache Geode provides a database-like consistency model, reliable transaction processing and a shared-nothing architecture to maintain very low latency performance with high concurrency processing</description>
   <url>http://geode.apache.org</url>
@@ -39,7 +39,7 @@
       <dependency>
         <groupId>org.apache.geode</groupId>
         <artifactId>geode-all-bom</artifactId>
-        <version>1.13.0-SNAPSHOT</version>
+        <version>${version}</version>
         <type>pom</type>
         <scope>import</scope>
       </dependency>
@@ -47,13 +47,13 @@
   </dependencyManagement>
   <dependencies>
     <dependency>
-      <groupId>org.apache.geode</groupId>
-      <artifactId>geode-common</artifactId>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-lang3</artifactId>
       <scope>compile</scope>
     </dependency>
     <dependency>
       <groupId>org.apache.geode</groupId>
-      <artifactId>geode-core</artifactId>
+      <artifactId>geode-common</artifactId>
       <scope>compile</scope>
     </dependency>
   </dependencies>
diff --git a/geode-common/build.gradle b/geode-common/build.gradle
index 52007bd..a8b59b3 100755
--- a/geode-common/build.gradle
+++ b/geode-common/build.gradle
@@ -26,3 +26,40 @@ dependencies {
   testImplementation('junit:junit')
   testImplementation('org.assertj:assertj-core')
 }
+
+def geodeProjects = ['geode-common-services','geode-common']
+
+jar {
+  doFirst {
+    def projectDependencies = []
+    def runtimeList = []
+
+    configurations.runtimeClasspath
+            .collect { it.name - ".jar" }
+            .each { dependency ->
+              if (dependency.startsWith("geode-")) {
+                projectDependencies.add(dependency)
+              } else {
+                runtimeList.add(dependency)
+              }
+            }
+
+    projectDependencies.each { projectDependency ->
+      geodeProjects.each { geodeProject ->
+        if (projectDependency.contains(geodeProject)) {
+          def childProject = project(":$geodeProject")
+
+          if (childProject != null) {
+            def collect = childProject.configurations.runtimeClasspath.collect { it.name - ".jar" }
+            runtimeList.removeAll(collect)
+            projectDependencies.removeAll(collect)
+          }
+        }
+      }
+    }
+    manifest {
+      attributes("Class-Path": runtimeList.join(' '))
+      attributes("Dependent-Modules": projectDependencies.join(' '))
+    }
+  }
+}
diff --git a/geode-modules/build.gradle b/geode-modules/build.gradle
index 7fa6b14..853c638 100644
--- a/geode-modules/build.gradle
+++ b/geode-modules/build.gradle
@@ -20,82 +20,148 @@ apply from: "${rootDir}/${scriptDir}/standard-subproject-configuration.gradle"
 apply from: "${project.projectDir}/../gradle/publish-java.gradle"
 apply from: "${project.projectDir}/../gradle/warnings.gradle"
 
+repositories {
+    mavenCentral()
+}
+
+apply plugin: 'nebula.facet'
+facets {
+    module1WithManifest {}
+    module2WithManifest {}
+    module3WithManifest {}
+    module4WithManifest {}
+    module1WithoutManifest {}
+    module2WithoutManifest {}
+    module3WithoutManifest {}
+    module4WithoutManifest {}
+}
+
 sourceSets {
-    module1 {
-        java.srcDir "src/testModules/module1/java"
-        resources.srcDir "src/testModules/module1/resources"
-        compileClasspath += configurations.compileClasspath
-        runtimeClasspath += configurations.runtimeClasspath
-    }
-    module2 {
-        java.srcDir "src/testModules/module2/java"
-        resources.srcDir "src/testModules/module2/resources"
-        compileClasspath += configurations.compileClasspath
-        runtimeClasspath += configurations.runtimeClasspath
-    }
-    module3 {
-        java.srcDir "src/testModules/module3/java"
-        resources.srcDir "src/testModules/module3/resources"
-        compileClasspath += configurations.compileClasspath
-        runtimeClasspath += configurations.runtimeClasspath
-    }
-    module4 {
-        java.srcDir "src/testModules/module4/java"
-        resources.srcDir "src/testModules/module4/resources"
+    module5WithManifest {
+        java.srcDir "src/testModules/module5WithManifest/java"
+        resources.srcDir "src/testModules/module5WithManifest/resources"
         compileClasspath += configurations.compileClasspath
         runtimeClasspath += configurations.runtimeClasspath
     }
 }
 
-task module1Jar(type: Jar, dependsOn: classes) {
-    description 'Assembles the jar archive that contains the module1 classes'
-    from sourceSets.module1.output
-    archiveName 'module1.jar'
-}
+def moduleTasks = []
+def moduleCopyTasks = []
+def geodeProjects = ['geode-common-services','geode-common']
 
-task module2Jar(type: Jar, dependsOn: classes) {
-    description 'Assembles the jar archive that contains the module2 classes'
-    from sourceSets.module2.output
-    archiveName 'module2.jar'
-}
+facets.each { thisConfig ->
+    if (thisConfig.name.contains("WithoutManifest")) {
+        tasks.create("${thisConfig.name}CopyRuntimeLibs", Copy) {
+            into "$buildDir/libs"
+            from configurations.getByName("${thisConfig.name}RuntimeClasspath")
+            moduleCopyTasks.add(it.name - ".jar")
+        }
+        tasks.create("${thisConfig.name}Jar", Jar) {
+            description 'Assembles the jar archive that contains the $it classes without a manifest file'
+            from sourceSets.getByName(thisConfig.name).output
 
-task module3Jar(type: Jar, dependsOn: classes) {
-    description 'Assembles the jar archive that contains the module3 classes'
-    from sourceSets.module3.output
-    archiveName 'module3.jar'
-}
+            def ss = sourceSets.getByName(thisConfig.name)
+            ss.java.source().setSrcDirs(["src/testModules/${thisConfig.name}/java"])
+            ss.resources.source().setSrcDirs(["src/testModules/${thisConfig.name}/resources"])
+
+            archiveName "${thisConfig.name}-1.0".concat(".jar")
+            moduleTasks.add(it.name)
+        }
+
+
+    }
+    if (thisConfig.name.contains("WithManifest")) {
+        tasks.create("${thisConfig.name}CopyRuntimeLibs", Copy) {
+            into "$buildDir/libs"
+            from configurations.getByName("${thisConfig.name}RuntimeClasspath")
+            moduleCopyTasks.add(it.name)
+        }
+        tasks.create("${thisConfig.name}Jar", Jar) {
+            description 'Assembles the jar archive that contains the $it classes with a manifest file'
+            from sourceSets.getByName(thisConfig.name).output
+
+            def sourceSet = sourceSets.getByName(thisConfig.name)
+            sourceSet.java.source().setSrcDirs(["src/testModules/${thisConfig.name}/java"])
+            sourceSet.resources.source().setSrcDirs(["src/testModules/${thisConfig.name}/resources"])
+
+            doFirst {
+                def projectDependencies = []
+                def runtimeList = []
+
+                configurations.getByName("${thisConfig.name}RuntimeClasspath")
+                        .collect { it.name - ".jar" }
+                        .each { dependency ->
+                            if (dependency.startsWith("geode-")) {
+                                projectDependencies.add(dependency)
+                            } else {
+                                runtimeList.add(dependency)
+                            }
+                        }
+
+                projectDependencies.each { projectDependency ->
+                    geodeProjects.each { geodeProject ->
+                        if (projectDependency.contains(geodeProject)) {
+                            def childProject = project(":$geodeProject")
 
-task module4Jar(type: Jar, dependsOn: classes) {
-    description 'Assembles the jar archive that contains the module4 classes'
-    from sourceSets.module4.output
-    archiveName 'module4.jar'
+                            if (childProject != null) {
+                                def collect = childProject.configurations.runtimeClasspath.collect { it.name - ".jar" }
+                                runtimeList.removeAll(collect)
+                                projectDependencies.removeAll(collect)
+                            }
+                        }
+                    }
+                }
+                manifest {
+                    attributes("Class-Path": runtimeList.join(' '))
+                    attributes("Dependent-Modules": projectDependencies.join(' '))
+                }
+            }
+            archiveName "${thisConfig.name}-1.0".concat(".jar")
+            moduleTasks.add(it.name)
+        }
+    }
 }
 
-tasks.test.dependsOn("module1Jar")
-tasks.test.dependsOn("module2Jar")
-tasks.test.dependsOn("module3Jar")
-tasks.test.dependsOn("module4Jar")
+task module5WithManifestJar(type: Jar, dependsOn: classes) {
+    description 'Assembles the jar archive that contains a manifest file wih an incorrect classpath location'
+    from sourceSets.module5WithManifest.output
+    doFirst {
+        manifest {
+            attributes("Class-Path": "invalidjar.jar")
+        }
+    }
+    archiveName 'module5WithManifest-1.0.jar'
+}
 
-repositories {
-    mavenCentral()
+task copyRuntimeLibs(type: Copy) {
+    into "$buildDir/libs"
+    from configurations.module1WithoutManifestRuntime
 }
 
+tasks.test.dependsOn("module5WithManifestJar")
+tasks.test.dependsOn(moduleTasks)
+tasks.test.dependsOn(moduleCopyTasks)
+
 dependencies {
     testCompile(group: 'junit', name: 'junit', version: '4.12')
     testImplementation('org.assertj:assertj-core')
 
-    compile(platform(project(':boms:geode-all-bom')))
-
-    compile(project(':geode-common'))
-    implementation(project(':geode-logging'))
-    implementation(project(':geode-log4j'))
+    testImplementation('org.mockito:mockito-core')
 
     compile(project(':geode-common-services'))
 
     implementation('org.apache.logging.log4j:log4j-core')
     compile('org.jboss.modules:jboss-modules')
 
-    module1Compile(sourceSets.test.output)
-    module2Compile(sourceSets.test.output)
-    module3Compile(sourceSets.test.output)
+    module1WithoutManifestCompileOnly(sourceSets.test.output)
+    module2WithoutManifestCompileOnly(sourceSets.test.output)
+    module3WithoutManifestCompileOnly(sourceSets.test.output)
+    module4WithoutManifestCompileOnly(sourceSets.test.output)
+    module1WithManifestCompileOnly(sourceSets.test.output)
+    module2WithManifestCompileOnly(sourceSets.test.output)
+    module3WithManifestCompileOnly(sourceSets.test.output)
+    module4WithManifestCompileOnly(sourceSets.test.output)
+    module5WithManifestCompileOnly(sourceSets.test.output)
+
+    module1WithManifestCompile('org.springframework:spring-core')
 }
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
deleted file mode 100644
index df06614..0000000
--- a/geode-modules/src/main/java/org/apache/geode/services/module/impl/GeodeModuleLoader.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.geode.services.module.impl;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.jboss.modules.DelegatingModuleLoader;
-import org.jboss.modules.Module;
-import org.jboss.modules.ModuleLoadException;
-import org.jboss.modules.ModuleLoader;
-import org.jboss.modules.ModuleSpec;
-
-import org.apache.geode.annotations.Experimental;
-
-/**
- * {@link ModuleLoader} for use by {@link JBossModuleServiceImpl}.
- */
-@Experimental
-public class GeodeModuleLoader extends DelegatingModuleLoader {
-  private Map<String, ModuleSpec> moduleSpecs = new HashMap<>();
-
-  public GeodeModuleLoader() {
-    super(Module.getSystemModuleLoader(), ModuleLoader.NO_FINDERS);
-  }
-
-  public void addModuleSpec(ModuleSpec moduleSpec) {
-    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);
-    if (moduleSpec == null) {
-      throw new ModuleLoadException(
-          String.format("ModuleSpec for Module %s could not be found", name));
-    }
-    return 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 14a088a..bf0b347 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
@@ -15,162 +15,232 @@
 
 package org.apache.geode.services.module.impl;
 
-import java.io.IOException;
 import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
 import java.util.Map;
-import java.util.jar.JarFile;
+import java.util.Optional;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.logging.log4j.Logger;
-import org.jboss.modules.DependencySpec;
-import org.jboss.modules.LocalDependencySpecBuilder;
 import org.jboss.modules.Module;
-import org.jboss.modules.ModuleDependencySpecBuilder;
+import org.jboss.modules.ModuleClassLoader;
 import org.jboss.modules.ModuleLoadException;
-import org.jboss.modules.ModuleSpec;
-import org.jboss.modules.PathUtils;
-import org.jboss.modules.ResourceLoader;
-import org.jboss.modules.ResourceLoaderSpec;
-import org.jboss.modules.ResourceLoaders;
-import org.jboss.modules.Version;
 
 import org.apache.geode.annotations.Experimental;
-import org.apache.geode.logging.internal.log4j.api.LogService;
 import org.apache.geode.services.module.ModuleDescriptor;
 import org.apache.geode.services.module.ModuleService;
+import org.apache.geode.services.module.internal.loader.GeodeModuleLoader;
+import org.apache.geode.services.result.ModuleServiceResult;
+import org.apache.geode.services.result.impl.Failure;
+import org.apache.geode.services.result.impl.Success;
 
 /**
- * Implementation of {@link ModuleService} using JBoss-Modules.
+ * Implementation of {@link ModuleService} using JBoss-Modules. This implementation uses
+ * JBossModules
+ * to load classes in a ClassLoader isolated manner.
+ *
+ * @see <a href="https://github.com/jboss-modules/jboss-modules">JBoss Modules</a>
+ *
+ * @since 1.14.0
  */
 @Experimental
 public class JBossModuleServiceImpl implements ModuleService {
 
-  private final Map<String, Module> modules = new HashMap<>();
+  private final Map<String, Module> modules = new ConcurrentHashMap<>();
 
-  private final GeodeModuleLoader moduleLoader = new GeodeModuleLoader();
+  private final GeodeModuleLoader moduleLoader;
 
   private final Logger logger;
 
-  public JBossModuleServiceImpl() {
-    this(LogService.getLogger());
-  }
-
   public JBossModuleServiceImpl(Logger logger) {
     this.logger = logger;
+    this.moduleLoader = new GeodeModuleLoader(logger);
   }
 
-  public Module getModule(String name) {
-    return modules.get(name);
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ModuleServiceResult<Boolean> registerModule(ModuleDescriptor moduleDescriptor) {
+    return moduleLoader.registerModuleDescriptor(moduleDescriptor);
   }
 
+  /**
+   * {@inheritDoc}
+   */
   @Override
-  public boolean loadModule(ModuleDescriptor moduleDescriptor) {
-    logger.debug(String.format("Beginning to load module %s", moduleDescriptor.getVersionedName()));
-
-    if (modules.containsKey(moduleDescriptor.getVersionedName())) {
-      logger
-          .warn(String.format("Module %s is already loaded.", moduleDescriptor.getVersionedName()));
-      return false;
+  public ModuleServiceResult<Boolean> loadModule(ModuleDescriptor moduleDescriptor) {
+    if (moduleDescriptor == null) {
+      return Failure.of("Load module failed due to moduleDescriptor being null");
     }
 
-    // Setting up new module.
-    ModuleSpec.Builder builder = ModuleSpec.build(moduleDescriptor.getVersionedName());
-    builder.setVersion(Version.parse(moduleDescriptor.getVersion()));
-    builder.addDependency(new LocalDependencySpecBuilder()
-        .setImportServices(true)
-        .setExport(true)
-        .build());
-
-    // Add dependencies to the module.
-    moduleDescriptor.getDependedOnModules().forEach(dependency -> {
-      logger.debug(String.format("Adding dependency on module %s", dependency));
-      builder.addDependency(new ModuleDependencySpecBuilder()
-          .setExport(true)
-          .setImportServices(true)
-          .setName(dependency)
-          .build());
-    });
+    String versionedName = moduleDescriptor.getName();
+    logger.debug(String.format("Beginning to load module %s", versionedName));
 
-    // Add resources to the module.
-    try {
-      for (String source : moduleDescriptor.getSources()) {
-        logger.debug(String.format("Adding resource %s to module", source));
-        ResourceLoader resourceLoader =
-            ResourceLoaders.createJarResourceLoader(new JarFile(source));
-        builder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec(resourceLoader));
-      }
-    } catch (IOException e) {
-      logger.error(e.getMessage(), e);
-      return false;
+    if (modules.containsKey(versionedName)) {
+      String errorMessage = String.format("Module %s is already loaded.", versionedName);
+      logger.warn(errorMessage);
+      return Failure.of(errorMessage);
     }
 
-    // Add dependency on the system classloader so modules can access classes that aren't in
-    // modules.
-    builder.addDependency(DependencySpec.createSystemDependencySpec(PathUtils.getPathSet(null)));
-
-    // Build and register the ModuleSpec
-    ModuleSpec moduleSpec = builder.create();
-    moduleLoader.addModuleSpec(moduleSpec);
+    return loadRegisteredModule(moduleDescriptor);
+  }
 
-    // Load the module and add it to the modules map.
+  /**
+   * Tries to load a module.
+   *
+   * @param moduleDescriptor the {@link ModuleDescriptor} describing the module.
+   * @return {@link Success} in the event of success and {@link Failure} in case of failure. Failure
+   *         to load a module usually happens due to the {@link ModuleDescriptor} not having been
+   *         registered.
+   *         {@link ModuleDescriptor} can be registered using
+   *         {@link ModuleService#registerModule(ModuleDescriptor)}
+   */
+  private ModuleServiceResult<Boolean> loadRegisteredModule(ModuleDescriptor moduleDescriptor) {
+    String versionedName = moduleDescriptor.getName();
     try {
-      modules.put(moduleDescriptor.getVersionedName(),
-          moduleLoader.loadModule(moduleSpec.getName()));
+      modules.put(versionedName, moduleLoader.loadModule(versionedName));
+      return Success.of(true);
     } catch (ModuleLoadException e) {
       logger.error(e.getMessage(), e);
-      return false;
+      return Failure.of(e.getMessage());
     }
-
-    logger
-        .debug(String.format("Module %s successfully loaded", moduleDescriptor.getVersionedName()));
-
-    return true;
   }
 
+  /**
+   * {@inheritDoc}
+   */
   @Override
-  public boolean unloadModule(String moduleName) {
+  public ModuleServiceResult<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;
+      String errorMessage =
+          String.format("Module %s could not be unloaded because it is not loaded", moduleName);
+      logger.warn(errorMessage);
+      return Failure.of(errorMessage);
     }
 
-    if (moduleLoader.unloadModule(modules.get(moduleName))) {
+    ModuleServiceResult<Boolean> unloadModuleResult =
+        moduleLoader.unloadModule(modules.get(moduleName));
+    if (unloadModuleResult.isSuccessful()) {
       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;
+    return unloadModuleResult;
   }
 
+  /**
+   * {@inheritDoc}
+   */
   @Override
-  public <T> List<T> loadService(Class<T> service) {
-    List<T> serviceImpls = new LinkedList<>();
+  public <T> ModuleServiceResult<Map<String, Set<T>>> loadService(Class<T> service) {
+    Map<String, Set<T>> serviceImpls = new HashMap<>();
 
     // Iterate over all the modules looking for implementations of service.
     modules.values().forEach((module) -> {
-      module.loadService(service).forEach((impl) -> {
-        // Check if class is already loaded.
-        // Modules with dependencies can cause duplicates without this check.
-        boolean duplicate = false;
-        for (T serviceImpl : serviceImpls) {
-          if (serviceImpl.getClass() == impl.getClass()) {
-            duplicate = true;
-            break;
-          }
-        }
-
-        // If impl is not a duplicate, add it to the list to return.
-        if (!duplicate) {
-          serviceImpls.add(impl);
-        }
+      module.loadService(service).forEach((serviceImpl) -> {
+        String moduleName = ((ModuleClassLoader) serviceImpl.getClass().getClassLoader()).getName();
+        Set<T> listOfServices = Optional.ofNullable(serviceImpls.get(moduleName))
+            .orElseGet(() -> createTreeSetWithClassLoaderComparator());
+        listOfServices.add(serviceImpl);
+        serviceImpls.put(moduleName, listOfServices);
       });
     });
 
-    return serviceImpls;
+    return Success.of(serviceImpls);
+  }
+
+  /**
+   *
+   * Create a Set<T> with a comparator on classname and ClassLoader to remove duplicates.
+   *
+   * @return empty set of type T
+   */
+  private <T> Set<T> createTreeSetWithClassLoaderComparator() {
+    return new TreeSet<>((o1, o2) -> {
+      if (o1 == null && o2 == null) {
+        return 0;
+      }
+      if (o1 == null) {
+        return 1;
+      }
+      if (o2 == null) {
+        return -1;
+      }
+      int classLoaderCompare = ((ModuleClassLoader) o1.getClass().getClassLoader()).getName()
+          .compareTo(((ModuleClassLoader) o2.getClass().getClassLoader()).getName());
+      if (classLoaderCompare == 0) {
+        return o1.getClass().getName().compareTo(o2.getClass().getName());
+      }
+      return classLoaderCompare;
+    });
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ModuleServiceResult<Class<?>> loadClass(String className,
+      ModuleDescriptor moduleDescriptor) {
+    Module module = modules.get(moduleDescriptor.getName());
+
+    if (module != null) {
+      return loadClassFromModule(className, module);
+    }
+    if (moduleLoader.hasRegisteredModule(moduleDescriptor.getName())) {
+      try {
+        module = moduleLoader.loadModule(moduleDescriptor.getName());
+        return loadClassFromModule(className, module);
+      } catch (ModuleLoadException e) {
+        logger.error(e);
+        return Failure.of(e.getMessage());
+      }
+    }
+    return Failure
+        .of(String.format("Module named: %s could be found. Please ensure it is registered",
+            moduleDescriptor.getName()));
+  }
+
+  /**
+   * Tries to load a class for name from a given module.
+   *
+   * @param className the classname that is to be loaded
+   * @param module the module from which the class is to be loaded from.
+   * @return {@link Success} with result type {@literal Class} or {@link Failure} with
+   *         {@literal String}
+   *         error message describing the reason for failure.
+   */
+  private ModuleServiceResult<Class<?>> loadClassFromModule(String className, Module module) {
+    try {
+      Class<?> loadedClass = module.getClassLoader().loadClass(className);
+      return Success.of(loadedClass);
+    } catch (ClassNotFoundException e) {
+      String errorMessage =
+          String.format("Could not find class for name: %s in module: %s", className,
+              module.getName());
+      logger.debug(errorMessage);
+      return Failure.of(errorMessage);
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ModuleServiceResult<Map<String, Class<?>>> loadClass(String className) {
+    Map<String, Class<?>> classes = new HashMap<>();
+    modules.values().forEach((module) -> {
+      try {
+        Class<?> loadedClass = module.getClassLoader().loadClass(className);
+        classes.put(module.getName(), loadedClass);
+      } catch (ClassNotFoundException e) {
+        logger.debug(String.format("Could not find class for name: %s in module: %s", className,
+            module.getName()));
+      }
+    });
+
+    return Success.of(classes);
   }
 }
diff --git a/geode-modules/src/main/java/org/apache/geode/services/module/internal/finder/DelegatingModuleFinder.java b/geode-modules/src/main/java/org/apache/geode/services/module/internal/finder/DelegatingModuleFinder.java
new file mode 100644
index 0000000..ef727aa
--- /dev/null
+++ b/geode-modules/src/main/java/org/apache/geode/services/module/internal/finder/DelegatingModuleFinder.java
@@ -0,0 +1,67 @@
+/*
+ * 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.geode.services.module.internal.finder;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.apache.logging.log4j.Logger;
+import org.jboss.modules.ModuleFinder;
+import org.jboss.modules.ModuleLoadException;
+import org.jboss.modules.ModuleLoader;
+import org.jboss.modules.ModuleSpec;
+
+/**
+ * This {@link ModuleFinder} delegates the finding of modules to an internal List of
+ * {@link ModuleFinder}.
+ * This {@link ModuleFinder} is used to overcome the restriction from the {@link ModuleLoader} that
+ * restricts the registered
+ * {@link ModuleFinder}s at construction time, which does not allow for a dynamic set of
+ * {@link ModuleFinder}s to be created at
+ * runtime.
+ *
+ * @see ModuleFinder
+ * @see ModuleLoader
+ * @see ModuleSpec
+ */
+public class DelegatingModuleFinder implements ModuleFinder {
+  private final Logger logger;
+
+  private final List<ModuleFinder> finders = new CopyOnWriteArrayList<>();
+
+  public DelegatingModuleFinder(Logger logger) {
+    this.logger = logger;
+  }
+
+  public void addModuleFinder(ModuleFinder finder) {
+    finders.add(finder);
+    logger.debug("Added finder " + finder);
+  }
+
+  @Override
+  public ModuleSpec findModule(String name, ModuleLoader delegateLoader)
+      throws ModuleLoadException {
+    for (ModuleFinder finder : finders) {
+      ModuleSpec moduleSpec = finder.findModule(name, delegateLoader);
+      if (moduleSpec != null) {
+        logger.debug(String.format("Found module specification for module named: %s ", name));
+        return moduleSpec;
+      }
+    }
+    logger.debug(String.format("No module specification for module named: %s found", name));
+    return null;
+  }
+}
diff --git a/geode-modules/src/main/java/org/apache/geode/services/module/internal/loader/GeodeModuleLoader.java b/geode-modules/src/main/java/org/apache/geode/services/module/internal/loader/GeodeModuleLoader.java
new file mode 100644
index 0000000..9ea0668
--- /dev/null
+++ b/geode-modules/src/main/java/org/apache/geode/services/module/internal/loader/GeodeModuleLoader.java
@@ -0,0 +1,129 @@
+/*
+ * 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.geode.services.module.internal.loader;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.log4j.Logger;
+import org.jboss.modules.DelegatingModuleLoader;
+import org.jboss.modules.GeodeJarModuleFinder;
+import org.jboss.modules.Module;
+import org.jboss.modules.ModuleFinder;
+import org.jboss.modules.ModuleLoadException;
+import org.jboss.modules.ModuleLoader;
+import org.jboss.modules.ModuleSpec;
+
+import org.apache.geode.annotations.Experimental;
+import org.apache.geode.services.module.ModuleDescriptor;
+import org.apache.geode.services.module.ModuleService;
+import org.apache.geode.services.module.impl.JBossModuleServiceImpl;
+import org.apache.geode.services.module.internal.finder.DelegatingModuleFinder;
+import org.apache.geode.services.result.ModuleServiceResult;
+import org.apache.geode.services.result.impl.Failure;
+import org.apache.geode.services.result.impl.Success;
+
+/**
+ * A custom implementation of {@link ModuleLoader} for use by {@link JBossModuleServiceImpl}.
+ * This implementation has reference to a {@link DelegatingModuleFinder} of type
+ * {@link ModuleFinder}
+ * to store a dynamically sized list of {@link ModuleFinder}.
+ *
+ * It also keeps track of registered {@link ModuleSpec} which have been created from
+ * {@link ModuleDescriptor}
+ * on a per module basis.
+ *
+ * @see ModuleLoader
+ * @see JBossModuleServiceImpl
+ * @see ModuleService
+ * @see ModuleServiceResult
+ * @see ModuleSpec
+ *
+ * @since 1.14.0
+ */
+@Experimental
+public class GeodeModuleLoader extends DelegatingModuleLoader {
+  private final DelegatingModuleFinder moduleFinder;
+  private final Map<String, ModuleSpec> moduleSpecs = new ConcurrentHashMap<>();
+  private final Logger logger;
+
+  public GeodeModuleLoader(Logger logger) {
+    this(new DelegatingModuleFinder(logger), logger);
+  }
+
+  private GeodeModuleLoader(DelegatingModuleFinder moduleFinder, Logger logger) {
+    super(Module.getSystemModuleLoader(), moduleFinder);
+    this.moduleFinder = moduleFinder;
+    this.logger = logger;
+  }
+
+  public ModuleServiceResult<Boolean> unloadModule(Module module) {
+    if (module != null && !StringUtils.isEmpty(module.getName())) {
+      return unloadModuleAndRemoveSpec(module);
+    } else {
+      String errorMessage =
+          "Module could not be unloaded because either the module or module name is null";
+      logger.debug(errorMessage);
+      return Failure.of(errorMessage);
+    }
+  }
+
+  private ModuleServiceResult<Boolean> unloadModuleAndRemoveSpec(Module module) {
+    try {
+      if (unloadModuleLocal(module.getName(), module)) {
+        moduleSpecs.remove(module.getName());
+        return Success.of(true);
+      } else {
+        String errorMessage = "Module could not be unloaded because it does not exist";
+        logger.debug(errorMessage);
+        return Failure.of(errorMessage);
+      }
+    } catch (SecurityException e) {
+      logger.error(e);
+      return Failure.of(String.format("Unloading of module: %s  failed due to exception: %s",
+          module.getName(), e.getMessage()));
+    }
+  }
+
+  public ModuleServiceResult<Boolean> registerModuleDescriptor(ModuleDescriptor descriptor) {
+    try {
+      moduleFinder.addModuleFinder(new GeodeJarModuleFinder(logger, descriptor));
+    } catch (IOException e) {
+      logger.error(e);
+      return Failure.of(String.format("Registering module: %s failed with error: %s",
+          descriptor.getName(), e.getMessage()));
+    }
+    return Success.of(true);
+  }
+
+  @Override
+  protected ModuleSpec findModule(String name) throws ModuleLoadException {
+    ModuleSpec moduleSpec = moduleSpecs.get(name);
+    if (moduleSpec == null) {
+      moduleSpec = moduleFinder.findModule(name, this);
+      if (moduleSpec != null) {
+        moduleSpecs.put(name, moduleSpec);
+      }
+    }
+    return moduleSpec;
+  }
+
+  public boolean hasRegisteredModule(String moduleName) {
+    return moduleSpecs.get(moduleName) != null;
+  }
+}
diff --git a/geode-modules/src/main/java/org/apache/geode/services/result/impl/Failure.java b/geode-modules/src/main/java/org/apache/geode/services/result/impl/Failure.java
new file mode 100644
index 0000000..8fe0602
--- /dev/null
+++ b/geode-modules/src/main/java/org/apache/geode/services/result/impl/Failure.java
@@ -0,0 +1,90 @@
+/*
+ * 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.geode.services.result.impl;
+
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+import org.apache.commons.lang3.StringUtils;
+
+import org.apache.geode.services.result.ModuleServiceResult;
+
+/**
+ * This type of {@link ModuleServiceResult} represents a failed operation. It contains the
+ * errorMessage
+ * for the failure.
+ *
+ * @param <SuccessType> the result type for a successful operation. Not used by the {@link Failure}
+ *        type
+ *        but required by the {@link ModuleServiceResult}
+ *
+ * @since 1.14.0
+ */
+public class Failure<SuccessType> implements ModuleServiceResult<SuccessType> {
+
+  private final String errorMessage;
+
+  private Failure(String errorMessage) {
+    this.errorMessage = errorMessage;
+  }
+
+  /**
+   * Creates a {@link Failure} object containing the errorMessage
+   *
+   * @param errorMessage the error message describing the reason for failure.
+   * @return an {@link Failure} instance containing the errorMessage
+   */
+  public static <T> Failure<T> of(String errorMessage) {
+    if (StringUtils.isEmpty(errorMessage)) {
+      throw new IllegalArgumentException("Error message cannot be null or empty");
+    }
+    return new Failure<>(errorMessage);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public <T> T map(Function<SuccessType, T> successFunction, Function<String, T> errorFunction) {
+    return errorFunction.apply(errorMessage);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public SuccessType getMessage() {
+    throw new RuntimeException("This Result is not of type Success.");
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String getErrorMessage() {
+    return errorMessage;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void ifFailure(Consumer<? super String> consumer) {
+    if (!isSuccessful()) {
+      consumer.accept(errorMessage);
+    }
+  }
+}
diff --git a/geode-modules/src/main/java/org/apache/geode/services/result/impl/Success.java b/geode-modules/src/main/java/org/apache/geode/services/result/impl/Success.java
new file mode 100644
index 0000000..af574f4
--- /dev/null
+++ b/geode-modules/src/main/java/org/apache/geode/services/result/impl/Success.java
@@ -0,0 +1,91 @@
+/*
+ * 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.geode.services.result.impl;
+
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+import org.apache.geode.services.result.ModuleServiceResult;
+
+/**
+ * This type of {@link ModuleServiceResult} represents a successful operation. It contains the
+ * return value
+ * of type <SuccessType>
+ *
+ * @param <SuccessType> the result type for a successful operation.
+ *
+ * @since 1.14.0
+ */
+public class Success<SuccessType> implements ModuleServiceResult<SuccessType> {
+
+  private final SuccessType result;
+
+  private Success(SuccessType result) {
+    this.result = result;
+  }
+
+  /**
+   * Creates a {@link Success} object containing the errorMessage
+   *
+   * @param result the return value of the successful operation
+   * @return an {@link Success} instance containing the return value
+   */
+  public static <T> Success<T> of(T result) {
+    return new Success<>(result);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public <T> T map(Function<SuccessType, T> successFunction, Function<String, T> errorFunction) {
+    return successFunction.apply(result);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public SuccessType getMessage() {
+    return result;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String getErrorMessage() {
+    throw new RuntimeException("This Result is not of type Failure.");
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean isSuccessful() {
+    return true;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void ifSuccessful(Consumer<? super SuccessType> consumer) {
+    if (isSuccessful()) {
+      consumer.accept(result);
+    }
+  }
+}
diff --git a/geode-modules/src/main/java/org/jboss/modules/GeodeJarModuleFinder.java b/geode-modules/src/main/java/org/jboss/modules/GeodeJarModuleFinder.java
new file mode 100644
index 0000000..ec4d200
--- /dev/null
+++ b/geode-modules/src/main/java/org/jboss/modules/GeodeJarModuleFinder.java
@@ -0,0 +1,293 @@
+/*
+ * 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.jboss.modules;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Optional;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.log4j.Logger;
+
+import org.apache.geode.services.module.ModuleDescriptor;
+
+/**
+ * A custom implementation of a {@link ModuleFinder}. This implementation is based on
+ * {@link JarModuleFinder}
+ * which creates a {@link ModuleSpec} from a {@link ModuleDescriptor}
+ * The {@link ModuleDescriptor} defines the module name, a set of {@link JarFile}s and/or dependent
+ * module names for Module.
+ *
+ * This {@link ModuleFinder} has the ability to set both resource paths and dependent module names
+ * from either
+ * the {@link ModuleDescriptor} or from a {@link Manifest} file within the {@link JarFile}.
+ *
+ * {@link Manifest} file must contain the attribute {@link Attributes.Name#CLASS_PATH} for resource
+ * paths and "Dependent-Modules"
+ * for a list of modules this modules depends on.
+ *
+ * In the case of both values being set on the {@link ModuleDescriptor} and within the
+ * {@link Manifest} file,
+ * the rule of addition is followed rather than failure.
+ *
+ * @see ModuleDescriptor
+ * @see ModuleSpec
+ * @see ModuleFinder
+ * @see JarModuleFinder
+ * @see JarFile
+ * @see Manifest
+ *
+ * @since 1.14.0
+ *
+ */
+public class GeodeJarModuleFinder implements ModuleFinder {
+
+  private final ModuleDescriptor moduleDescriptor;
+  private final String moduleName;
+  private final List<JarFile> sourceJarFiles;
+  private final Logger logger;
+
+  private static final String[] EMPTY_STRING_ARRAY = new String[0];
+  private static final String DEPENDENT_MODULES = "Dependent-Modules";
+  private static final List<String> EMPTY_LIST = new ArrayList<>();
+
+  /**
+   * Constructs a {@link GeodeJarModuleFinder} using a {@link Logger} and {@link ModuleDescriptor}.
+   * In the the case of incorrect/missing resource paths an {@link IOException} will be thrown.
+   *
+   * @param logger a Logger to log messages
+   * @param moduleDescriptor the {@link ModuleDescriptor} describing the module
+   * @throws IOException is thrown in the case of incorrect/missing resource paths.
+   */
+  public GeodeJarModuleFinder(final Logger logger, final ModuleDescriptor moduleDescriptor)
+      throws IOException {
+    this.moduleName = moduleDescriptor.getName();
+    this.sourceJarFiles = parseSourcesIntoJarFiles(moduleDescriptor);
+    this.logger = logger;
+    this.moduleDescriptor = moduleDescriptor;
+  }
+
+  /**
+   * Processes the {@link ModuleDescriptor} resource paths into a collection of {@link JarFile}
+   *
+   * @param moduleDescriptor the {@link ModuleDescriptor} for the module
+   * @return a collection of {@link JarFile} from the {@link ModuleDescriptor}
+   * @throws IOException is thrown in the case of incorrect/missing resources
+   */
+  private List<JarFile> parseSourcesIntoJarFiles(ModuleDescriptor moduleDescriptor)
+      throws IOException {
+    List<JarFile> results = new LinkedList<>();
+    for (String sourcePath : moduleDescriptor.getResourceJarPaths()) {
+      results.add(new JarFile(sourcePath, true));
+    }
+    return results;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ModuleSpec findModule(String name, ModuleLoader delegateLoader)
+      throws ModuleLoadException {
+    if (this.moduleName.equals(name)) {
+      return findModuleOfRegisteredJars(name);
+    }
+    return null;
+  }
+
+  /**
+   * Create a {@link ModuleSpec} for the registered Module.
+   * It creates a {@link ModuleSpec} for the name, processes each of the {@link JarFile} in the
+   * {@link #sourceJarFiles} collection and adds dependencies to other modules.
+   *
+   * @param name the module name
+   * @return a {@link ModuleSpec} from the corresponding {@link ModuleDescriptor}
+   * @throws ModuleLoadException in case of failure loading resource paths
+   */
+  private ModuleSpec findModuleOfRegisteredJars(String name) throws ModuleLoadException {
+    ModuleSpec.Builder moduleSpecBuilder = getModuleSpec(name);
+    for (JarFile jarFile : sourceJarFiles) {
+      registerJarFile(moduleSpecBuilder, jarFile);
+    }
+    createDependenciesForModules(moduleSpecBuilder, moduleDescriptor.getDependedOnModules());
+    moduleSpecBuilder.addDependency(DependencySpec.createSystemDependencySpec(JDKPaths.JDK));
+    return moduleSpecBuilder.create();
+  }
+
+  /**
+   * Processes a single {@link JarFile}. Processes the optionally included {@link Manifest} and adds
+   * itself to the {@link ModuleSpec} as a source resource.
+   *
+   * @param moduleSpecBuilder the builder for the {@link ModuleSpec}
+   * @param jarFile the {@link JarFile} to be processed
+   * @throws ModuleLoadException in case of failure loading resource paths
+   */
+  private void registerJarFile(ModuleSpec.Builder moduleSpecBuilder, JarFile jarFile)
+      throws ModuleLoadException {
+    processManifestFileEntries(moduleSpecBuilder, jarFile);
+
+    moduleSpecBuilder.addResourceRoot(ResourceLoaderSpec
+        .createResourceLoaderSpec(ResourceLoaders.createJarResourceLoader(jarFile)));
+  }
+
+  /**
+   * Processes a collection of modules and adds them to the dependent modules list for the
+   * {@link ModuleSpec}
+   *
+   * @param moduleSpecBuilder the builder for the {@link ModuleSpec}
+   * @param modulesDependencies a list of module names on which this module depends on
+   */
+  private void createDependenciesForModules(ModuleSpec.Builder moduleSpecBuilder,
+      Collection<String> modulesDependencies) {
+    for (String moduleDependency : modulesDependencies) {
+      moduleSpecBuilder.addDependency(new ModuleDependencySpecBuilder()
+          .setExport(true)
+          .setImportServices(true)
+          .setName(moduleDependency)
+          .build());
+    }
+  }
+
+  /**
+   * Processes the {@link Manifest} and populates both the resource paths and dependent modules from
+   * it.
+   * The {@link Manifest} file optionally includes a {@link Attributes.Name#CLASS_PATH} attribute,
+   * describing the resource paths to be included
+   * or an attribute {@link #DEPENDENT_MODULES} describing a list of dependent module names.
+   *
+   * @param moduleSpecBuilder the builder for the {@link ModuleSpec}
+   * @param jarFile the {@link JarFile} which contains a {@link Manifest} file.
+   * @throws ModuleLoadException in case of failure loading resource paths
+   */
+  private void processManifestFileEntries(ModuleSpec.Builder moduleSpecBuilder, JarFile jarFile)
+      throws ModuleLoadException {
+    Optional<Manifest> manifestFromJar = getManifestFromJar(jarFile);
+    if (manifestFromJar.isPresent()) {
+      String rootPath =
+          jarFile.getName().substring(0, jarFile.getName().lastIndexOf(File.separator));
+      Attributes mainAttributes = manifestFromJar.get().getMainAttributes();
+      processClasspathFromManifest(moduleSpecBuilder, rootPath,
+          mainAttributes.getValue(Attributes.Name.CLASS_PATH));
+
+      processManifestDependents(moduleSpecBuilder, mainAttributes.getValue(DEPENDENT_MODULES));
+    }
+  }
+
+  /**
+   * Process the {@link Manifest} file for dependent module names. The {@link Manifest} file must
+   * contain
+   * attribute {@link #DEPENDENT_MODULES} entries for this to be successful.
+   *
+   * @param moduleSpecBuilder the builder for the {@link ModuleSpec}
+   * @param dependentModules a String (' ') single space delimited of dependent module names
+   */
+  private void processManifestDependents(ModuleSpec.Builder moduleSpecBuilder,
+      String dependentModules) {
+    List<String> dependentModulesEntries = !StringUtils.isEmpty(dependentModules) ? Arrays
+        .asList(dependentModules.split(" ")) : EMPTY_LIST;
+    createDependenciesForModules(moduleSpecBuilder, dependentModulesEntries);
+  }
+
+  /**
+   * Process the {@link Manifest} file for resource paths to include. The {@link Manifest} file must
+   * contain
+   * attribute {@link Attributes.Name#CLASS_PATH} entries for this to be successful.
+   *
+   * @param builder the builder for the {@link ModuleSpec}
+   * @param rootPath the root path for the source {@link JarFile}.
+   * @param classpath a String (' ') single space delimited list of resource paths.
+   * @throws ModuleLoadException in the case of incorrect/missing resource
+   */
+  private void processClasspathFromManifest(ModuleSpec.Builder builder, String rootPath,
+      String classpath) throws ModuleLoadException {
+    String[] classpathEntries =
+        !StringUtils.isEmpty(classpath) ? classpath.split(" ") : EMPTY_STRING_ARRAY;
+    for (String classpathEntry : classpathEntries) {
+      if (!classpathEntry.isEmpty()) {
+
+        File file = getFileForPath(rootPath, classpathEntry);
+        try {
+          builder.addResourceRoot(ResourceLoaderSpec
+              .createResourceLoaderSpec(
+                  ResourceLoaders.createJarResourceLoader(new JarFile(file, true))));
+        } catch (IOException e) {
+          logger.error(String.format(
+              "File for name: %s could not be loaded as a dependent jar file at location: %s",
+              classpathEntry, file.getName()));
+          throw new ModuleLoadException(e);
+        }
+      }
+    }
+  }
+
+  /**
+   * Returns a {@link File} for the path = rootPath + fileName.
+   * Checks if the fileName includes ".jar" and adds it if it is not included.
+   *
+   * @param rootPath the root path where the file is to be located
+   * @param fileName the filename of the {@link JarFile} within the rootPath
+   * @return file represented by the rootPath + fileName.
+   */
+  private File getFileForPath(String rootPath, String fileName) {
+    if (fileName.endsWith(".jar")) {
+      return new File(rootPath + File.separator + fileName);
+    } else {
+      return new File(rootPath + File.separator + fileName + ".jar");
+    }
+  }
+
+  /**
+   * Creates and returns a {@link ModuleSpec.Builder} for the name specified
+   *
+   * @param name the name of the module
+   * @return a {@link ModuleSpec.Builder}
+   */
+  private ModuleSpec.Builder getModuleSpec(String name) {
+    ModuleSpec.Builder builder = ModuleSpec.build(name);
+    builder.addDependency(new LocalDependencySpecBuilder()
+        .setImportServices(true)
+        .setExport(true)
+        .build());
+
+    return builder;
+  }
+
+  /**
+   * Returns a {@link Manifest} file from the {@link JarFile}
+   *
+   * @param jarFile the {@link JarFile} from which to retrieve the {@link Manifest} file
+   * @return an {@link Optional} containing a {@link Manifest} file from the {@link JarFile}. In the
+   *         case of no {@link Manifest} file
+   *         being present, an {@link Optional#empty()} shall be returned.
+   */
+  private Optional<Manifest> getManifestFromJar(JarFile jarFile) {
+    try {
+      return Optional.ofNullable(jarFile.getManifest());
+    } catch (IOException e) {
+      logger.info(
+          String.format("Unable to find manifest file for jar ile name: %s", jarFile.getName()));
+    }
+    return Optional.empty();
+  }
+}
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
deleted file mode 100644
index be14780..0000000
--- a/geode-modules/src/test/java/org/apache/geode/services/module/impl/JBossModuleServiceImplTest.java
+++ /dev/null
@@ -1,616 +0,0 @@
-/*
- * 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.geode.services.module.impl;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-import java.util.List;
-
-import org.jboss.modules.Module;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import org.apache.geode.InvalidService;
-import org.apache.geode.TestService;
-import org.apache.geode.services.module.ModuleDescriptor;
-
-public class JBossModuleServiceImplTest {
-
-  private static final String MODULE1_PATH =
-      System.getProperty("user.dir") + "/../libs/module1.jar";
-  private static final String MODULE2_PATH =
-      System.getProperty("user.dir") + "/../libs/module2.jar";
-  private static final String MODULE3_PATH =
-      System.getProperty("user.dir") + "/../libs/module3.jar";
-  private static final String MODULE4_PATH =
-      System.getProperty("user.dir") + "/../libs/module4.jar";
-
-  private static final String MODULE1_MESSAGE = "Hello from Module1!";
-  private static final String MODULE2_MESSAGE = "Hello from Module2!";
-
-  private JBossModuleServiceImpl moduleService;
-
-  @Before
-  public void setup() {
-    moduleService = new JBossModuleServiceImpl();
-  }
-
-  @After
-  public void teardown() {
-    moduleService = null;
-  }
-
-  @Test
-  public void modulesNotAccessibleFromSystemClassloaderNoModulesLoaded() {
-    assertThatThrownBy(() -> {
-      this.getClass().getClassLoader().loadClass("org.apache.geode.Module1");
-    }).isInstanceOf(ClassNotFoundException.class);
-
-    assertThatThrownBy(() -> {
-      this.getClass().getClassLoader().loadClass("org.apache.geode.Module2");
-    }).isInstanceOf(ClassNotFoundException.class);
-  }
-
-  @Test
-  public void modulesNotAccessibleFromSystemClassloaderWithModulesLoaded() {
-    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
-        .fromSources(MODULE1_PATH)
-        .build();
-    ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module2", "1.0")
-        .fromSources(MODULE2_PATH)
-        .build();
-    moduleService.loadModule(module1Descriptor);
-    moduleService.loadModule(module2Descriptor);
-
-    assertThatThrownBy(() -> {
-      this.getClass().getClassLoader().loadClass("org.apache.geode.Module1");
-    }).isInstanceOf(ClassNotFoundException.class);
-
-    assertThatThrownBy(() -> {
-      this.getClass().getClassLoader().loadClass("org.apache.geode.Module2");
-    }).isInstanceOf(ClassNotFoundException.class);
-  }
-
-  @Test
-  public void loadSingleModuleFromSingleJarNoDependencies() throws ClassNotFoundException {
-    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
-        .fromSources(MODULE1_PATH)
-        .build();
-    assertThat(moduleService.loadModule(module1Descriptor)).isTrue();
-
-    moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
-        .loadClass("org.apache.geode.Module1");
-  }
-
-  @Test
-  public void loadSingleModuleFromMultipleJarsNoDependencies() throws ClassNotFoundException {
-    ModuleDescriptor moduleDescriptor = new ModuleDescriptor.Builder("multiJarModule", "1.0")
-        .fromSources(MODULE1_PATH, MODULE2_PATH)
-        .build();
-    assertThat(moduleService.loadModule(moduleDescriptor)).isTrue();
-
-    moduleService.getModule(moduleDescriptor.getVersionedName()).getClassLoader()
-        .loadClass("org.apache.geode.Module1");
-    moduleService.getModule(moduleDescriptor.getVersionedName()).getClassLoader()
-        .loadClass("org.apache.geode.Module2");
-  }
-
-  @Test
-  public void loadMultipleModulesFromMultipleJarsNoDependencies() throws ClassNotFoundException {
-    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
-        .fromSources(MODULE1_PATH, MODULE2_PATH)
-        .build();
-    ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module2", "1.0")
-        .fromSources(MODULE3_PATH, MODULE4_PATH)
-        .build();
-
-    assertThat(moduleService.loadModule(module1Descriptor)).isTrue();
-    assertThat(moduleService.loadModule(module2Descriptor)).isTrue();
-
-    moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
-        .loadClass("org.apache.geode.Module1");
-    moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
-        .loadClass("org.apache.geode.Module2");
-
-    moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
-        .loadClass("org.apache.geode.Module3");
-    moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
-        .loadClass("org.apache.geode.Module4");
-  }
-
-  @Test
-  public void modulesCannotAccessOtherModulesMultipleModulesFromMultipleJarsNoDependencies()
-      throws ClassNotFoundException {
-    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
-        .fromSources(MODULE1_PATH, MODULE2_PATH)
-        .build();
-    ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module2", "1.0")
-        .fromSources(MODULE3_PATH, MODULE4_PATH)
-        .build();
-
-    moduleService.loadModule(module1Descriptor);
-    moduleService.loadModule(module2Descriptor);
-
-    assertThatThrownBy(() -> {
-      moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
-          .loadClass("org.apache.geode.Module3");
-    }).isInstanceOf(ClassNotFoundException.class);
-    assertThatThrownBy(() -> {
-      moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
-          .loadClass("org.apache.geode.Module4");
-    }).isInstanceOf(ClassNotFoundException.class);
-
-    assertThatThrownBy(() -> {
-      moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
-          .loadClass("org.apache.geode.Module1");
-    }).isInstanceOf(ClassNotFoundException.class);
-    assertThatThrownBy(() -> {
-      moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
-          .loadClass("org.apache.geode.Module2");
-    }).isInstanceOf(ClassNotFoundException.class);
-  }
-
-  @Test
-  public void loadMultipleModulesFromMultipleJarsWithDependencies() throws ClassNotFoundException {
-    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
-        .fromSources(MODULE1_PATH, MODULE2_PATH)
-        .build();
-    ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module2", "1.0")
-        .fromSources(MODULE3_PATH, MODULE4_PATH)
-        .dependsOnModules(module1Descriptor.getVersionedName())
-        .build();
-
-    assertThat(moduleService.loadModule(module1Descriptor)).isTrue();
-    assertThat(moduleService.loadModule(module2Descriptor)).isTrue();
-
-    moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
-        .loadClass("org.apache.geode.Module1");
-    moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
-        .loadClass("org.apache.geode.Module2");
-    moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
-        .loadClass("org.apache.geode.Module3");
-    moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
-        .loadClass("org.apache.geode.Module4");
-  }
-
-  @Test
-  public void dependenciesDoNotGoBothWaysMultipleModulesFromMultipleJars()
-      throws ClassNotFoundException {
-    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
-        .fromSources(MODULE1_PATH, MODULE2_PATH)
-        .build();
-    ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module2", "1.0")
-        .fromSources(MODULE3_PATH, MODULE4_PATH)
-        .dependsOnModules(module1Descriptor.getVersionedName())
-        .build();
-
-    moduleService.loadModule(module1Descriptor);
-    moduleService.loadModule(module2Descriptor);
-
-    assertThatThrownBy(() -> {
-      moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
-          .loadClass("org.apache.geode.Module3");
-    }).isInstanceOf(ClassNotFoundException.class);
-    assertThatThrownBy(() -> {
-      moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
-          .loadClass("org.apache.geode.Module4");
-    }).isInstanceOf(ClassNotFoundException.class);
-  }
-
-  @Test
-  public void loadMultipleModulesFromSingleJarNoDependencies() throws ClassNotFoundException {
-    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
-        .fromSources(MODULE1_PATH)
-        .build();
-    ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module2", "1.0")
-        .fromSources(MODULE2_PATH)
-        .build();
-    assertThat(moduleService.loadModule(module1Descriptor)).isTrue();
-    assertThat(moduleService.loadModule(module2Descriptor)).isTrue();
-
-    moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
-        .loadClass("org.apache.geode.Module1");
-    moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
-        .loadClass("org.apache.geode.Module2");
-  }
-
-  @Test
-  public void modulesCannotAccessOtherModulesMultipleModulesFromSingleJarNoDependencies()
-      throws ClassNotFoundException {
-    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
-        .fromSources(MODULE1_PATH)
-        .build();
-    ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module2", "1.0")
-        .fromSources(MODULE2_PATH)
-        .build();
-    moduleService.loadModule(module1Descriptor);
-    moduleService.loadModule(module2Descriptor);
-
-    assertThatThrownBy(() -> {
-      moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
-          .loadClass("org.apache.geode.Module2");
-    }).isInstanceOf(ClassNotFoundException.class);
-
-    assertThatThrownBy(() -> {
-      moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
-          .loadClass("org.apache.geode.Module1");
-    }).isInstanceOf(ClassNotFoundException.class);
-  }
-
-  @Test
-  public void loadMultipleModulesFromSingleJarWithDependencies() throws ClassNotFoundException {
-    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
-        .fromSources(MODULE1_PATH)
-        .build();
-    ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module2", "1.0")
-        .fromSources(MODULE2_PATH)
-        .dependsOnModules(module1Descriptor.getVersionedName())
-        .build();
-    assertThat(moduleService.loadModule(module1Descriptor)).isTrue();
-    assertThat(moduleService.loadModule(module2Descriptor)).isTrue();
-
-    moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
-        .loadClass("org.apache.geode.Module1");
-    moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
-        .loadClass("org.apache.geode.Module2");
-    moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
-        .loadClass("org.apache.geode.Module1");
-  }
-
-  @Test
-  public void dependenciesDoNotGoBothWaysMultipleModulesFromSingleJar()
-      throws ClassNotFoundException {
-    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
-        .fromSources(MODULE1_PATH)
-        .build();
-    ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module2", "1.0")
-        .fromSources(MODULE2_PATH)
-        .dependsOnModules(module1Descriptor.getVersionedName())
-        .build();
-    moduleService.loadModule(module1Descriptor);
-    moduleService.loadModule(module2Descriptor);
-
-    assertThatThrownBy(() -> {
-      moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
-          .loadClass("org.apache.geode.Module2");
-    }).isInstanceOf(ClassNotFoundException.class);
-  }
-
-  @Test
-  public void loadModuleMultipleTimes() throws ClassNotFoundException {
-    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
-        .fromSources(MODULE1_PATH)
-        .build();
-    assertThat(moduleService.loadModule(module1Descriptor)).isTrue();
-    assertThat(moduleService.loadModule(module1Descriptor)).isFalse();
-
-    moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
-        .loadClass("org.apache.geode.Module1");
-  }
-
-  @Test
-  public void loadModulesWithSameNameAndDifferentVersions() throws ClassNotFoundException {
-    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
-        .fromSources(MODULE1_PATH)
-        .build();
-    moduleService.loadModule(module1Descriptor);
-    ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module1", "2.0")
-        .fromSources(MODULE2_PATH)
-        .build();
-    moduleService.loadModule(module2Descriptor);
-
-    moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
-        .loadClass("org.apache.geode.Module1");
-    assertThatThrownBy(() -> {
-      moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
-          .loadClass("org.apache.geode.Module2");
-    }).isInstanceOf(ClassNotFoundException.class);
-
-    moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
-        .loadClass("org.apache.geode.Module2");
-    assertThatThrownBy(() -> {
-      moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
-          .loadClass("org.apache.geode.Module1");
-    }).isInstanceOf(ClassNotFoundException.class);
-  }
-
-  @Test
-  public void loadModuleFromInvalidSource() {
-    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
-        .fromSources("/there/is/nothing/here.jar")
-        .build();
-    assertThat(moduleService.loadModule(module1Descriptor)).isFalse();
-    assertThat(moduleService.getModule(module1Descriptor.getVersionedName())).isNull();
-  }
-
-  @Test
-  public void loadModuleFromMixOfValidAndInvalidSources() {
-    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
-        .fromSources("/there/is/nothing/here.jar", MODULE1_PATH)
-        .build();
-    assertThat(moduleService.loadModule(module1Descriptor)).isFalse();
-    assertThat(moduleService.getModule(module1Descriptor.getVersionedName())).isNull();
-  }
-
-  @Test
-  public void loadModuleWithInvalidDependencies() {
-    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
-        .fromSources(MODULE1_PATH)
-        .dependsOnModules("this_is_invalid")
-        .build();
-    assertThat(moduleService.loadModule(module1Descriptor)).isFalse();
-    assertThat(moduleService.getModule(module1Descriptor.getVersionedName())).isNull();
-  }
-
-  @Test
-  public void loadModuleWithMixOfValidAndInvalidDependencies() {
-    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
-        .fromSources(MODULE1_PATH)
-        .build();
-    ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module2", "1.0")
-        .fromSources(MODULE2_PATH)
-        .dependsOnModules("this_is_invalid", module1Descriptor.getVersionedName())
-        .build();
-    moduleService.loadModule(module1Descriptor);
-    assertThat(moduleService.loadModule(module2Descriptor)).isFalse();
-    assertThat(moduleService.getModule(module2Descriptor.getVersionedName())).isNull();
-  }
-
-  @Test
-  public void getModuleNoModulesLoaded() {
-    assertThat(moduleService.getModule("module1:1.0")).isNull();
-  }
-
-  @Test
-  public void getModuleWithSingeModuleLoaded() {
-    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
-        .fromSources(MODULE1_PATH)
-        .build();
-    moduleService.loadModule(module1Descriptor);
-    Module module = moduleService.getModule(module1Descriptor.getVersionedName());
-    assertThat(module).isNotNull();
-    assertThat(module.getName()).isEqualTo(module1Descriptor.getVersionedName());
-  }
-
-  @Test
-  public void getModuleWithMultipleModulesLoaded() {
-    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);
-
-    Module module1 = moduleService.getModule(module1Descriptor.getVersionedName());
-    assertThat(module1).isNotNull();
-    assertThat(module1.getName()).isEqualTo(module1Descriptor.getVersionedName());
-
-    Module module2 = moduleService.getModule(module2Descriptor.getVersionedName());
-    assertThat(module2).isNotNull();
-    assertThat(module2.getName()).isEqualTo(module2Descriptor.getVersionedName());
-  }
-
-  @Test
-  public void loadServiceNoModulesLoaded() {
-    assertThat(moduleService.loadService(TestService.class)).isEmpty();
-  }
-
-  @Test
-  public void loadServiceNoModulesImplementService() {
-    assertThat(moduleService.loadService(InvalidService.class)).isEmpty();
-  }
-
-  @Test
-  public void loadServiceFromSingleModule() {
-    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
-        .fromSources(MODULE1_PATH)
-        .build();
-    moduleService.loadModule(module1Descriptor);
-
-    List<TestService> serviceList = moduleService.loadService(TestService.class);
-    assertThat(serviceList.size()).isEqualTo(1);
-    assertThat(serviceList.get(0).sayHello()).isEqualTo(MODULE1_MESSAGE);
-  }
-
-  @Test
-  public void loadServicesFromMultipleModules() {
-    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
-        .fromSources(MODULE1_PATH)
-        .build();
-    ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module2", "1.0")
-        .fromSources(MODULE2_PATH)
-        .build();
-    moduleService.loadModule(module1Descriptor);
-    moduleService.loadModule(module2Descriptor);
-
-    List<TestService> serviceList = moduleService.loadService(TestService.class);
-    assertThat(serviceList.size()).isEqualTo(2);
-    assertThat(serviceList.stream().map(TestService::sayHello)).contains(MODULE1_MESSAGE,
-        MODULE2_MESSAGE);
-  }
-
-  @Test
-  public void loadServicesFromCompositeModule() {
-    ModuleDescriptor moduleDescriptor = new ModuleDescriptor.Builder("module1", "1.0")
-        .fromSources(MODULE1_PATH, MODULE2_PATH)
-        .build();
-    moduleService.loadModule(moduleDescriptor);
-
-    List<TestService> serviceList = moduleService.loadService(TestService.class);
-    assertThat(serviceList.size()).isEqualTo(2);
-    assertThat(serviceList.stream().map(TestService::sayHello)).contains(MODULE1_MESSAGE,
-        MODULE2_MESSAGE);
-  }
-
-  @Test
-  public void loadServiceFromModulesWithDependencies() {
-    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);
-
-    List<TestService> serviceList = moduleService.loadService(TestService.class);
-    assertThat(serviceList.size()).isEqualTo(2);
-    assertThat(serviceList.stream().map(TestService::sayHello)).contains(MODULE1_MESSAGE,
-        MODULE2_MESSAGE);
-  }
-
-  @Test
-  public void loadServiceFromModuleWithDuplicateContents() {
-    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
-        .fromSources(MODULE1_PATH, MODULE1_PATH)
-        .build();
-    moduleService.loadModule(module1Descriptor);
-
-    List<TestService> serviceList = moduleService.loadService(TestService.class);
-    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/test/java/org/apache/geode/services/module/impl/JBossModuleServiceImplWithoutPopulatedManifestFileTest.java b/geode-modules/src/test/java/org/apache/geode/services/module/impl/JBossModuleServiceImplWithoutPopulatedManifestFileTest.java
new file mode 100644
index 0000000..3756506
--- /dev/null
+++ b/geode-modules/src/test/java/org/apache/geode/services/module/impl/JBossModuleServiceImplWithoutPopulatedManifestFileTest.java
@@ -0,0 +1,819 @@
+/*
+ * 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.geode.services.module.impl;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOfType;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.apache.logging.log4j.LogManager;
+import org.jboss.modules.ModuleClassLoader;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.apache.geode.InvalidService;
+import org.apache.geode.TestService;
+import org.apache.geode.services.module.ModuleDescriptor;
+import org.apache.geode.services.module.ModuleService;
+import org.apache.geode.services.result.ModuleServiceResult;
+
+public class JBossModuleServiceImplWithoutPopulatedManifestFileTest {
+
+  private static final String MODULE1_PATH =
+      System.getProperty("user.dir") + "/../libs/module1WithoutManifest-1.0.jar";
+  private static final String MODULE2_PATH =
+      System.getProperty("user.dir") + "/../libs/module2WithoutManifest-1.0.jar";
+  private static final String MODULE3_PATH =
+      System.getProperty("user.dir") + "/../libs/module3WithoutManifest-1.0.jar";
+  private static final String MODULE4_PATH =
+      System.getProperty("user.dir") + "/../libs/module4WithoutManifest-1.0.jar";
+
+  private static final String MODULE1_MESSAGE = "Hello from Module1!";
+  private static final String MODULE2_MESSAGE = "Hello from Module2!";
+
+  private ModuleService moduleService;
+
+  @Before
+  public void setup() {
+    moduleService = new JBossModuleServiceImpl(LogManager.getLogger());
+  }
+
+  @After
+  public void teardown() {
+    moduleService = null;
+  }
+
+  @Test
+  public void modulesNotAccessibleFromSystemClassloaderNoModulesLoaded() {
+    ModuleServiceResult<Map<String, Class<?>>> mapModuleServiceResult = moduleService
+        .loadClass("org.apache.geode.ModuleService1");
+    assertThat(mapModuleServiceResult.isSuccessful()).isEqualTo(true);
+    assertThat(mapModuleServiceResult.getMessage().size()).isEqualTo(0);
+
+    mapModuleServiceResult = moduleService
+        .loadClass("org.apache.geode.ModuleService2");
+    assertThat(mapModuleServiceResult.isSuccessful()).isEqualTo(true);
+    assertThat(mapModuleServiceResult.getMessage().size()).isEqualTo(0);
+  }
+
+  @Test
+  public void modulesNotAccessibleFromSystemClassloaderWithModulesLoaded() {
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH)
+            .build();
+    ModuleDescriptor module2Descriptor =
+        new ModuleDescriptor.Builder("module2WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE2_PATH)
+            .build();
+
+    assertThat(moduleService.registerModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.registerModule(module2Descriptor).isSuccessful()).isTrue();
+
+    assertThat(moduleService.loadModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.loadModule(module2Descriptor).isSuccessful()).isTrue();
+
+    assertThatExceptionOfType(ClassNotFoundException.class)
+        .isThrownBy(
+            () -> this.getClass().getClassLoader().loadClass("org.apache.geode.ModuleService1"));
+    assertThatExceptionOfType(ClassNotFoundException.class)
+        .isThrownBy(
+            () -> this.getClass().getClassLoader().loadClass("org.apache.geode.ModuleService2"));
+  }
+
+  @Test
+  public void loadSingleModuleFromSingleJarNoDependencies() {
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH)
+            .build();
+
+    assertThat(moduleService.registerModule(module1Descriptor).isSuccessful()).isTrue();
+
+    assertThat(moduleService.loadModule(module1Descriptor).isSuccessful()).isTrue();
+
+    loadClassAndAssert("org.apache.geode.ModuleService1", module1Descriptor);
+  }
+
+  @Test
+  public void loadSingleModuleFromMultipleJarsNoDependencies() {
+    ModuleDescriptor moduleDescriptor = new ModuleDescriptor.Builder("multiJarModule", "1.0")
+        .fromResourcePaths(MODULE1_PATH, MODULE2_PATH)
+        .build();
+
+    assertThat(moduleService.registerModule(moduleDescriptor).isSuccessful()).isTrue();
+
+    assertThat(moduleService.loadModule(moduleDescriptor).isSuccessful()).isTrue();
+
+    loadClassAndAssert("org.apache.geode.ModuleService1", moduleDescriptor);
+
+    loadClassAndAssert("org.apache.geode.ModuleService2", moduleDescriptor);
+  }
+
+  private void loadClassAndAssert(String className, ModuleDescriptor loadFromModule,
+      ModuleDescriptor moduleClassLoader) {
+    ModuleServiceResult<Class<?>> loadClassResult =
+        moduleService.loadClass(className, loadFromModule);
+    assertThat(loadClassResult.isSuccessful()).isTrue();
+    String moduleNameFromClassLoader =
+        ((ModuleClassLoader) loadClassResult.getMessage().getClassLoader()).getName();
+    assertThat(moduleNameFromClassLoader).isEqualTo(moduleClassLoader.getName());
+  }
+
+  private void loadClassAndAssert(String className, ModuleDescriptor moduleDescriptor) {
+    loadClassAndAssert(className, moduleDescriptor, moduleDescriptor);
+  }
+
+  private void loadClassAndAssertFailure(String className, ModuleDescriptor moduleDescriptor,
+      String expectedErrorMessage) {
+    ModuleServiceResult<Class<?>> loadClassResult =
+        moduleService.loadClass(className, moduleDescriptor);
+    assertThat(loadClassResult.isSuccessful()).isFalse();
+    assertThat(loadClassResult.getErrorMessage()).isEqualTo(expectedErrorMessage);
+  }
+
+  @Test
+  public void loadMultipleModulesFromMultipleJarsNoDependencies() {
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH, MODULE2_PATH)
+            .build();
+    ModuleDescriptor module2Descriptor =
+        new ModuleDescriptor.Builder("module2WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE3_PATH, MODULE4_PATH)
+            .build();
+
+    assertThat(moduleService.registerModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.registerModule(module2Descriptor).isSuccessful()).isTrue();
+
+    assertThat(moduleService.loadModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.loadModule(module2Descriptor).isSuccessful()).isTrue();
+
+    loadClassAndAssert("org.apache.geode.ModuleService1", module1Descriptor);
+    loadClassAndAssert("org.apache.geode.ModuleService2", module1Descriptor);
+
+    loadClassAndAssert("org.apache.geode.ModuleService3", module2Descriptor);
+    loadClassAndAssert("org.apache.geode.ModuleService4", module2Descriptor);
+  }
+
+  @Test
+  public void modulesCannotAccessOtherModulesMultipleModulesFromMultipleJarsNoDependencies() {
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH, MODULE2_PATH)
+            .build();
+    ModuleDescriptor module2Descriptor =
+        new ModuleDescriptor.Builder("module2WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE3_PATH, MODULE4_PATH)
+            .build();
+
+    assertThat(moduleService.registerModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.registerModule(module2Descriptor).isSuccessful()).isTrue();
+
+    assertThat(moduleService.loadModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.loadModule(module2Descriptor).isSuccessful()).isTrue();
+
+    loadClassAndAssertFailure("org.apache.geode.ModuleService3", module1Descriptor,
+        "Could not find class for name: org.apache.geode.ModuleService3 in module: module1WithoutManifest-1.0");
+    loadClassAndAssertFailure("org.apache.geode.ModuleService4", module1Descriptor,
+        "Could not find class for name: org.apache.geode.ModuleService4 in module: module1WithoutManifest-1.0");
+    loadClassAndAssertFailure("org.apache.geode.ModuleService1", module2Descriptor,
+        "Could not find class for name: org.apache.geode.ModuleService1 in module: module2WithoutManifest-1.0");
+    loadClassAndAssertFailure("org.apache.geode.ModuleService2", module2Descriptor,
+        "Could not find class for name: org.apache.geode.ModuleService2 in module: module2WithoutManifest-1.0");
+  }
+
+  @Test
+  public void loadMultipleModulesFromMultipleJarsWithDependencies() {
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH, MODULE2_PATH)
+            .build();
+    ModuleDescriptor module2Descriptor =
+        new ModuleDescriptor.Builder("module2WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE3_PATH, MODULE4_PATH)
+            .dependsOnModules(module1Descriptor.getName())
+            .build();
+
+    assertThat(moduleService.registerModule(module2Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.registerModule(module1Descriptor).isSuccessful()).isTrue();
+
+    assertThat(moduleService.loadModule(module2Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.loadModule(module1Descriptor).isSuccessful()).isTrue();
+
+    loadClassAndAssert("org.apache.geode.ModuleService1", module2Descriptor, module1Descriptor);
+    loadClassAndAssert("org.apache.geode.ModuleService2", module2Descriptor, module1Descriptor);
+    loadClassAndAssert("org.apache.geode.ModuleService3", module2Descriptor);
+    loadClassAndAssert("org.apache.geode.ModuleService4", module2Descriptor);
+  }
+
+  @Test
+  public void dependenciesDoNotGoBothWaysMultipleModulesFromMultipleJars() {
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH, MODULE2_PATH)
+            .build();
+    ModuleDescriptor module2Descriptor =
+        new ModuleDescriptor.Builder("module2WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE3_PATH, MODULE4_PATH)
+            .dependsOnModules(module1Descriptor.getName())
+            .build();
+
+    assertThat(moduleService.registerModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.registerModule(module2Descriptor).isSuccessful()).isTrue();
+
+    assertThat(moduleService.loadModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.loadModule(module2Descriptor).isSuccessful()).isTrue();
+
+    loadClassAndAssert("org.apache.geode.ModuleService1", module2Descriptor, module1Descriptor);
+    loadClassAndAssert("org.apache.geode.ModuleService2", module2Descriptor, module1Descriptor);
+
+    loadClassAndAssertFailure("org.apache.geode.ModuleService3", module1Descriptor,
+        "Could not find class for name: org.apache.geode.ModuleService3 in module: module1WithoutManifest-1.0");
+    loadClassAndAssertFailure("org.apache.geode.ModuleService4", module1Descriptor,
+        "Could not find class for name: org.apache.geode.ModuleService4 in module: module1WithoutManifest-1.0");
+  }
+
+  @Test
+  public void loadMultipleModulesFromSingleJarNoDependencies() {
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH)
+            .build();
+    ModuleDescriptor module2Descriptor =
+        new ModuleDescriptor.Builder("module2WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE2_PATH)
+            .build();
+
+    assertThat(moduleService.registerModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.registerModule(module2Descriptor).isSuccessful()).isTrue();
+
+    assertThat(moduleService.loadModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.loadModule(module2Descriptor).isSuccessful()).isTrue();
+
+    loadClassAndAssert("org.apache.geode.ModuleService1", module1Descriptor);
+    loadClassAndAssert("org.apache.geode.ModuleService2", module2Descriptor);
+  }
+
+  @Test
+  public void modulesCannotAccessOtherModulesMultipleModulesFromSingleJarNoDependencies() {
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH)
+            .build();
+    ModuleDescriptor module2Descriptor =
+        new ModuleDescriptor.Builder("module2WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE2_PATH)
+            .build();
+
+    assertThat(moduleService.registerModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.registerModule(module2Descriptor).isSuccessful()).isTrue();
+
+    assertThat(moduleService.loadModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.loadModule(module2Descriptor).isSuccessful()).isTrue();
+
+    loadClassAndAssertFailure("org.apache.geode.ModuleService2", module1Descriptor,
+        "Could not find class for name: org.apache.geode.ModuleService2 in module: module1WithoutManifest-1.0");
+    loadClassAndAssertFailure("org.apache.geode.ModuleService1", module2Descriptor,
+        "Could not find class for name: org.apache.geode.ModuleService1 in module: module2WithoutManifest-1.0");
+  }
+
+  @Test
+  public void loadMultipleModulesWithDependencies() {
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH)
+            .build();
+    ModuleDescriptor module2Descriptor =
+        new ModuleDescriptor.Builder("module2WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE2_PATH)
+            .dependsOnModules(module1Descriptor.getName())
+            .build();
+
+    assertThat(moduleService.registerModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.registerModule(module2Descriptor).isSuccessful()).isTrue();
+
+    assertThat(moduleService.loadModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.loadModule(module2Descriptor).isSuccessful()).isTrue();
+
+    loadClassAndAssert("org.apache.geode.ModuleService1", module1Descriptor);
+    loadClassAndAssert("org.apache.geode.ModuleService2", module2Descriptor);
+    loadClassAndAssert("org.apache.geode.ModuleService1", module2Descriptor, module1Descriptor);
+  }
+
+  @Test
+  public void loadMultipleModulesFromSingleSourceWithDependencies() {
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH)
+            .build();
+    ModuleDescriptor module2Descriptor =
+        new ModuleDescriptor.Builder("module2WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE2_PATH)
+            .dependsOnModules(module1Descriptor.getName())
+            .build();
+
+    assertThat(moduleService.registerModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.registerModule(module2Descriptor).isSuccessful()).isTrue();
+
+    assertThat(moduleService.loadModule(module2Descriptor).isSuccessful()).isTrue();
+
+    loadClassAndAssert("org.apache.geode.ModuleService1", module1Descriptor);
+    loadClassAndAssert("org.apache.geode.ModuleService2", module2Descriptor);
+    loadClassAndAssert("org.apache.geode.ModuleService1", module2Descriptor, module1Descriptor);
+  }
+
+  @Test
+  public void dependenciesDoNotGoBothWaysMultipleModulesFromSingleJar() {
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH)
+            .build();
+    ModuleDescriptor module2Descriptor =
+        new ModuleDescriptor.Builder("module2WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE2_PATH)
+            .dependsOnModules(module1Descriptor.getName())
+            .build();
+
+    assertThat(moduleService.registerModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.registerModule(module2Descriptor).isSuccessful()).isTrue();
+
+    assertThat(moduleService.loadModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.loadModule(module2Descriptor).isSuccessful()).isTrue();
+
+    loadClassAndAssertFailure("org.apache.geode.ModuleService2", module1Descriptor,
+        "Could not find class for name: org.apache.geode.ModuleService2 in module: module1WithoutManifest-1.0");
+    loadClassAndAssert("org.apache.geode.ModuleService1", module2Descriptor, module1Descriptor);
+  }
+
+  @Test
+  public void loadModuleMultipleTimes() {
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH)
+            .build();
+
+    assertThat(moduleService.registerModule(module1Descriptor).isSuccessful()).isTrue();
+
+    assertThat(moduleService.loadModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.loadModule(module1Descriptor).isSuccessful()).isFalse();
+
+    loadClassAndAssert("org.apache.geode.ModuleService1", module1Descriptor);
+  }
+
+  @Test
+  public void loadModulesWithSameNameAndDifferentVersions() {
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH)
+            .build();
+    assertThat(moduleService.registerModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.loadModule(module1Descriptor).isSuccessful()).isTrue();
+
+    ModuleDescriptor module2Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "2.0")
+            .fromResourcePaths(MODULE2_PATH)
+            .build();
+    assertThat(moduleService.registerModule(module2Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.loadModule(module2Descriptor).isSuccessful()).isTrue();
+
+    loadClassAndAssert("org.apache.geode.ModuleService1", module1Descriptor);
+    loadClassAndAssertFailure("org.apache.geode.ModuleService2", module1Descriptor,
+        "Could not find class for name: org.apache.geode.ModuleService2 in module: module1WithoutManifest-1.0");
+    loadClassAndAssert("org.apache.geode.ModuleService2", module2Descriptor);
+    loadClassAndAssertFailure("org.apache.geode.ModuleService1", module2Descriptor,
+        "Could not find class for name: org.apache.geode.ModuleService1 in module: module1WithoutManifest-2.0");
+  }
+
+  @Test
+  public void registerModuleFromInvalidSource() {
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths("/there/is/nothing/here.jar")
+            .build();
+
+    ModuleServiceResult<Boolean> moduleServiceResult =
+        moduleService.registerModule(module1Descriptor);
+    assertThat(moduleServiceResult.isSuccessful()).isFalse();
+    assertThat(moduleServiceResult.getErrorMessage()).contains(
+        "Registering module: module1WithoutManifest-1.0 failed with error: /there/is/nothing/here.jar");
+  }
+
+  @Test
+  public void loadModuleFromMixOfValidAndInvalidSources() {
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths("/there/is/nothing/here.jar", MODULE1_PATH)
+            .build();
+    assertThat(moduleService.loadModule(module1Descriptor).isSuccessful()).isFalse();
+  }
+
+  @Test
+  public void loadModuleWithInvalidDependencies() {
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH)
+            .dependsOnModules("this_is_invalid")
+            .build();
+    assertThat(moduleService.loadModule(module1Descriptor).isSuccessful()).isFalse();
+  }
+
+  @Test
+  public void loadModuleWithMixOfValidAndInvalidDependencies() {
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH)
+            .build();
+    ModuleDescriptor module2Descriptor =
+        new ModuleDescriptor.Builder("module2WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE2_PATH)
+            .dependsOnModules("this_is_invalid", module1Descriptor.getName())
+            .build();
+
+    assertThat(moduleService.registerModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.registerModule(module2Descriptor).isSuccessful()).isTrue();
+
+    assertThat(moduleService.loadModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.loadModule(module2Descriptor).isSuccessful()).isFalse();
+  }
+
+  @Test
+  public void loadServiceNoModulesLoaded() {
+    ModuleServiceResult<Map<String, Set<TestService>>> loadServiceResult =
+        moduleService.loadService(TestService.class);
+    assertThat(loadServiceResult.isSuccessful()).isTrue();
+    assertThat(loadServiceResult.getMessage()).isEmpty();
+  }
+
+  @Test
+  public void loadServiceNoModulesImplementService() {
+    ModuleServiceResult<Map<String, Set<InvalidService>>> loadServiceResult =
+        moduleService.loadService(InvalidService.class);
+    assertThat(loadServiceResult.isSuccessful()).isTrue();
+    assertThat(loadServiceResult.getMessage()).isEmpty();
+  }
+
+  @Test
+  public void loadServiceFromSingleModule() {
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH)
+            .build();
+
+    assertThat(moduleService.registerModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.loadModule(module1Descriptor).isSuccessful()).isTrue();
+
+    ModuleServiceResult<Map<String, Set<TestService>>> serviceList =
+        moduleService.loadService(TestService.class);
+    assertThat(serviceList.isSuccessful()).isTrue();
+    assertThat(serviceList.getMessage().size()).isEqualTo(1);
+    assertThat(serviceList.getMessage().get(module1Descriptor.getName()).stream()
+        .map(TestService::sayHello).findFirst().orElse("Error")).isEqualTo(MODULE1_MESSAGE);
+  }
+
+  @Test
+  public void loadServicesFromMultipleModules() {
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH)
+            .build();
+    ModuleDescriptor module2Descriptor =
+        new ModuleDescriptor.Builder("module2WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE2_PATH)
+            .build();
+
+    assertThat(moduleService.registerModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.registerModule(module2Descriptor).isSuccessful()).isTrue();
+
+    assertThat(moduleService.loadModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.loadModule(module2Descriptor).isSuccessful()).isTrue();
+
+    ModuleServiceResult<Map<String, Set<TestService>>> serviceList =
+        moduleService.loadService(TestService.class);
+    assertThat(serviceList.isSuccessful()).isTrue();
+    assertThat(serviceList.getMessage().size()).isEqualTo(2);
+    Collection<Set<TestService>> values = serviceList.getMessage().values();
+    List<String> results = new ArrayList<>();
+    for (Set<TestService> services : values) {
+      results.addAll(services.stream().map(TestService::sayHello).collect(Collectors.toList()));
+    }
+    assertThat(results).contains(MODULE1_MESSAGE, MODULE2_MESSAGE);
+  }
+
+  @Test
+  public void loadServicesFromCompositeModule() {
+    ModuleDescriptor moduleDescriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH, MODULE2_PATH)
+            .build();
+
+    assertThat(moduleService.registerModule(moduleDescriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.loadModule(moduleDescriptor).isSuccessful()).isTrue();
+
+    ModuleServiceResult<Map<String, Set<TestService>>> serviceList =
+        moduleService.loadService(TestService.class);
+    assertThat(serviceList.isSuccessful()).isTrue();
+    assertThat(serviceList.getMessage().size()).isEqualTo(1);
+    assertThat(serviceList.getMessage().get(moduleDescriptor.getName()).size())
+        .isEqualTo(2);
+
+    Collection<Set<TestService>> values = serviceList.getMessage().values();
+    List<String> results = new ArrayList<>();
+    for (Set<TestService> services : values) {
+      results.addAll(services.stream().map(TestService::sayHello).collect(Collectors.toList()));
+    }
+    assertThat(results).contains(MODULE1_MESSAGE, MODULE2_MESSAGE);
+  }
+
+  @Test
+  public void loadServiceFromModulesWithDependencies() {
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH)
+            .build();
+
+    ModuleDescriptor module2Descriptor =
+        new ModuleDescriptor.Builder("module2WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE2_PATH)
+            .dependsOnModules(module1Descriptor.getName())
+            .build();
+
+    assertThat(moduleService.registerModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.registerModule(module2Descriptor).isSuccessful()).isTrue();
+
+    assertThat(moduleService.loadModule(module2Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.loadModule(module1Descriptor).isSuccessful()).isTrue();
+
+    ModuleServiceResult<Map<String, Set<TestService>>> serviceList =
+        moduleService.loadService(TestService.class);
+    assertThat(serviceList.isSuccessful()).isTrue();
+    assertThat(serviceList.getMessage().size()).isEqualTo(2);
+    assertThat(serviceList.getMessage().get(module1Descriptor.getName()).size())
+        .isEqualTo(1);
+    assertThat(serviceList.getMessage().get(module2Descriptor.getName()).size())
+        .isEqualTo(1);
+
+    Collection<Set<TestService>> values = serviceList.getMessage().values();
+    List<String> results = new ArrayList<>();
+    for (Set<TestService> services : values) {
+      results.addAll(services.stream().map(TestService::sayHello).collect(Collectors.toList()));
+    }
+    assertThat(results).contains(MODULE1_MESSAGE, MODULE2_MESSAGE);
+  }
+
+  @Test
+  public void loadServiceFromModuleWithDuplicateContents() {
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH, MODULE1_PATH)
+            .build();
+
+    assertThat(moduleService.registerModule(module1Descriptor).isSuccessful()).isTrue();
+
+    assertThat(moduleService.loadModule(module1Descriptor).isSuccessful()).isTrue();
+
+    ModuleServiceResult<Map<String, Set<TestService>>> serviceList =
+        moduleService.loadService(TestService.class);
+    assertThat(serviceList.isSuccessful()).isTrue();
+    assertThat(serviceList.getMessage().size()).isEqualTo(1);
+    assertThat(serviceList.getMessage().get(module1Descriptor.getName()).stream()
+        .map(TestService::sayHello).findFirst().orElse("Error")).isEqualTo(MODULE1_MESSAGE);
+  }
+
+  @Test
+  public void unloadModule() {
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH)
+            .build();
+
+    assertThat(moduleService.registerModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.loadModule(module1Descriptor).isSuccessful()).isTrue();
+
+    ModuleServiceResult<Map<String, Set<TestService>>> loadServiceResult =
+        moduleService.loadService(TestService.class);
+    assertThat(loadServiceResult.isSuccessful()).isTrue();
+    assertThat(loadServiceResult.getMessage().size()).isEqualTo(1);
+
+    assertThat(moduleService.unloadModule(module1Descriptor.getName()).isSuccessful())
+        .isTrue();
+
+    loadServiceResult = moduleService.loadService(TestService.class);
+    assertThat(loadServiceResult.isSuccessful()).isTrue();
+    assertThat(loadServiceResult.getMessage()).isEmpty();
+  }
+
+  @Test
+  public void unloadModuleFromMultipleJars() {
+    ModuleDescriptor moduleDescriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH, MODULE2_PATH)
+            .build();
+
+    assertThat(moduleService.registerModule(moduleDescriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.loadModule(moduleDescriptor).isSuccessful()).isTrue();
+
+    ModuleServiceResult<Map<String, Set<TestService>>> loadServiceResult =
+        moduleService.loadService(TestService.class);
+    assertThat(loadServiceResult.isSuccessful()).isTrue();
+    assertThat(loadServiceResult.getMessage().size()).isEqualTo(1);
+
+    assertThat(moduleService.unloadModule(moduleDescriptor.getName()).isSuccessful())
+        .isTrue();
+
+    loadServiceResult = moduleService.loadService(TestService.class);
+    assertThat(loadServiceResult.isSuccessful()).isTrue();
+    assertThat(loadServiceResult.getMessage()).isEmpty();
+  }
+
+  @Test
+  public void unloadOneOfMultipleModules() {
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH)
+            .build();
+    ModuleDescriptor module2Descriptor =
+        new ModuleDescriptor.Builder("module2WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE2_PATH)
+            .build();
+
+    assertThat(moduleService.registerModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.registerModule(module2Descriptor).isSuccessful()).isTrue();
+
+    assertThat(moduleService.loadModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.loadModule(module2Descriptor).isSuccessful()).isTrue();
+
+    ModuleServiceResult<Map<String, Set<TestService>>> loadServiceResult =
+        moduleService.loadService(TestService.class);
+    assertThat(loadServiceResult.isSuccessful()).isTrue();
+    assertThat(loadServiceResult.getMessage().size()).isEqualTo(2);
+    assertThat(loadServiceResult.getMessage().get(module1Descriptor.getName()).size())
+        .isEqualTo(1);
+    assertThat(loadServiceResult.getMessage().get(module2Descriptor.getName()).size())
+        .isEqualTo(1);
+
+    assertThat(moduleService.unloadModule(module1Descriptor.getName()).isSuccessful())
+        .isTrue();
+
+    loadClassAndAssert("org.apache.geode.ModuleService2", module2Descriptor);
+
+    loadServiceResult = moduleService.loadService(TestService.class);
+    assertThat(loadServiceResult.isSuccessful()).isTrue();
+    assertThat(loadServiceResult.getMessage().size()).isEqualTo(1);
+    assertThat(loadServiceResult.getMessage().get(module2Descriptor.getName()).size())
+        .isEqualTo(1);
+  }
+
+  @Test
+  public void unloadInvalidModuleName() {
+    assertThat(moduleService.unloadModule("invalidModuleName").isSuccessful()).isFalse();
+  }
+
+  @Test
+  public void reloadUnloadedModule() {
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH)
+            .build();
+
+    assertThat(moduleService.registerModule(module1Descriptor).isSuccessful()).isTrue();
+
+    assertThat(moduleService.loadModule(module1Descriptor).isSuccessful()).isTrue();
+
+    ModuleServiceResult<Map<String, Set<TestService>>> loadServiceResult =
+        moduleService.loadService(TestService.class);
+    assertThat(loadServiceResult.isSuccessful()).isTrue();
+    assertThat(loadServiceResult.getMessage().size()).isEqualTo(1);
+    assertThat(loadServiceResult.getMessage().get(module1Descriptor.getName()).size())
+        .isEqualTo(1);
+
+    assertThat(moduleService.unloadModule(module1Descriptor.getName()).isSuccessful())
+        .isTrue();
+
+    loadServiceResult = moduleService.loadService(TestService.class);
+    assertThat(loadServiceResult.isSuccessful()).isTrue();
+    assertThat(loadServiceResult.getMessage()).isEmpty();
+
+    assertThat(moduleService.loadModule(module1Descriptor).isSuccessful()).isTrue();
+
+    loadServiceResult = moduleService.loadService(TestService.class);
+    assertThat(loadServiceResult.isSuccessful()).isTrue();
+    assertThat(loadServiceResult.getMessage().size()).isEqualTo(1);
+    assertThat(loadServiceResult.getMessage().get(module1Descriptor.getName()).size())
+        .isEqualTo(1);
+  }
+
+  @Test
+  public void unloadModuleWithDependencies() {
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH)
+            .build();
+
+    ModuleDescriptor module2Descriptor =
+        new ModuleDescriptor.Builder("module2WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE2_PATH)
+            .dependsOnModules(module1Descriptor.getName())
+            .build();
+
+    assertThat(moduleService.registerModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.registerModule(module2Descriptor).isSuccessful()).isTrue();
+
+    assertThat(moduleService.loadModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.loadModule(module2Descriptor).isSuccessful()).isTrue();
+
+    ModuleServiceResult<Map<String, Set<TestService>>> loadServiceResult =
+        moduleService.loadService(TestService.class);
+    assertThat(loadServiceResult.isSuccessful()).isTrue();
+    assertThat(loadServiceResult.getMessage().size()).isEqualTo(2);
+    assertThat(loadServiceResult.getMessage().get(module1Descriptor.getName()).size())
+        .isEqualTo(1);
+    assertThat(loadServiceResult.getMessage().get(module2Descriptor.getName()).size())
+        .isEqualTo(1);
+
+    assertThat(moduleService.unloadModule(module2Descriptor.getName()).isSuccessful())
+        .isTrue();
+
+    loadClassAndAssert("org.apache.geode.ModuleService1", module1Descriptor);
+
+    loadServiceResult = moduleService.loadService(TestService.class);
+    assertThat(loadServiceResult.isSuccessful()).isTrue();
+    assertThat(loadServiceResult.getMessage().size()).isEqualTo(1);
+    assertThat(loadServiceResult.getMessage().get(module1Descriptor.getName()).size())
+        .isEqualTo(1);
+  }
+
+  @Test
+  public void unloadModuleTwice() {
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH)
+            .build();
+
+    assertThat(moduleService.registerModule(module1Descriptor).isSuccessful()).isTrue();
+
+    assertThat(moduleService.loadModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.unloadModule(module1Descriptor.getName()).isSuccessful())
+        .isTrue();
+    assertThat(moduleService.unloadModule(module1Descriptor.getName()).isSuccessful())
+        .isFalse();
+  }
+
+  @Test
+  public void unloadModuleWithSourceSharedByOtherModule() {
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH, MODULE2_PATH)
+            .build();
+
+    ModuleDescriptor module2Descriptor =
+        new ModuleDescriptor.Builder("module2WithoutManifest", "1.0")
+            .fromResourcePaths(MODULE2_PATH, MODULE3_PATH)
+            .build();
+
+    assertThat(moduleService.registerModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.registerModule(module2Descriptor).isSuccessful()).isTrue();
+
+    assertThat(moduleService.loadModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.loadModule(module2Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.unloadModule(module1Descriptor.getName()).isSuccessful())
+        .isTrue();
+
+    loadClassAndAssert("org.apache.geode.ModuleService2", module2Descriptor);
+    loadClassAndAssert("org.apache.geode.ModuleService3", module2Descriptor);
+
+    ModuleServiceResult<Map<String, Set<TestService>>> loadServiceResult =
+        moduleService.loadService(TestService.class);
+    assertThat(loadServiceResult.isSuccessful()).isTrue();
+    assertThat(loadServiceResult.getMessage().size()).isEqualTo(1);
+    assertThat(loadServiceResult.getMessage().keySet().toArray()[0])
+        .isEqualTo(module2Descriptor.getName());
+
+    Set<TestService> testServices =
+        loadServiceResult.getMessage().get(module2Descriptor.getName());
+    assertThat(testServices.size()).isEqualTo(2);
+    assertThat(testServices.stream().map(service -> service.getClass().getName()))
+        .containsExactlyInAnyOrder("org.apache.geode.ModuleService2",
+            "org.apache.geode.ModuleService3");
+  }
+}
diff --git a/geode-modules/src/test/java/org/apache/geode/services/module/impl/JBossModulesServiceImplWithPopulatedManifestFileTest.java b/geode-modules/src/test/java/org/apache/geode/services/module/impl/JBossModulesServiceImplWithPopulatedManifestFileTest.java
new file mode 100644
index 0000000..145d7ac
--- /dev/null
+++ b/geode-modules/src/test/java/org/apache/geode/services/module/impl/JBossModulesServiceImplWithPopulatedManifestFileTest.java
@@ -0,0 +1,144 @@
+/*
+ * 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.geode.services.module.impl;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.logging.log4j.LogManager;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.apache.geode.services.module.ModuleDescriptor;
+import org.apache.geode.services.module.ModuleService;
+import org.apache.geode.services.result.ModuleServiceResult;
+import org.apache.geode.services.result.impl.Failure;
+
+public class JBossModulesServiceImplWithPopulatedManifestFileTest {
+
+  private static final String MODULE1_PATH =
+      System.getProperty("user.dir") + "/../libs/module1WithManifest-1.0.jar";
+  private static final String MODULE2_PATH =
+      System.getProperty("user.dir") + "/../libs/module2WithManifest-1.0.jar";
+  private static final String MODULE3_PATH =
+      System.getProperty("user.dir") + "/../libs/module3WithManifest-1.0.jar";
+  private static final String MODULE4_PATH =
+      System.getProperty("user.dir") + "/../libs/module4WithManifest-1.0.jar";
+  private static final String MODULE5_PATH =
+      System.getProperty("user.dir") + "/../libs/module5WithManifest-1.0.jar";
+  private static final String GEODE_COMMONS_SERVICES_PATH =
+      System.getProperty("user.dir") + "/../libs/geode-common-services-1.14.0-build.0.jar";
+  private static final String GEODE_COMMONS_PATH =
+      System.getProperty("user.dir") + "/../libs/geode-common-1.14.0-build.0.jar";
+
+  private ModuleService moduleService;
+  private ModuleDescriptor geodeCommonsServiceDescriptor;
+  private ModuleDescriptor geodeCommonDescriptor;
+
+  @Before
+  public void setup() {
+    moduleService = new JBossModuleServiceImpl(LogManager.getLogger());
+    geodeCommonsServiceDescriptor =
+        new ModuleDescriptor.Builder("geode-common-services-1.14.0-build.0")
+            .fromResourcePaths(GEODE_COMMONS_SERVICES_PATH)
+            .build();
+
+    geodeCommonDescriptor = new ModuleDescriptor.Builder("geode-common-1.14.0-build.0")
+        .fromResourcePaths(GEODE_COMMONS_PATH)
+        .build();
+  }
+
+  @Test
+  public void loadJarWithManifestAndClasspathAttribute() {
+    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1WithManifest", "1.0")
+        .fromResourcePaths(MODULE1_PATH)
+        .build();
+
+    ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module2WithManifest", "1.0")
+        .fromResourcePaths(MODULE2_PATH)
+        .build();
+
+    assertThat(moduleService.registerModule(geodeCommonsServiceDescriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.registerModule(geodeCommonDescriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.registerModule(module1Descriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.registerModule(module2Descriptor).isSuccessful()).isTrue();
+
+    loadModuleAndAssert(geodeCommonsServiceDescriptor);
+    loadModuleAndAssert(module1Descriptor);
+    loadModuleAndAssert(module2Descriptor);
+
+    ModuleServiceResult<Map<String, Class<?>>> loadClassResult =
+        moduleService.loadClass("org.springframework.util.StringUtils");
+
+    assertThat(loadClassResult.isSuccessful()).isTrue();
+
+    Map<String, Class<?>> message = loadClassResult.getMessage();
+    assertThat(message.size()).isEqualTo(1);
+    assertThat(message.keySet().toArray()[0]).isEqualTo(module1Descriptor.getName());
+  }
+
+  private void loadModuleAndAssert(ModuleDescriptor descriptor) {
+    ModuleServiceResult<Boolean> loadModuleResult = moduleService.loadModule(descriptor);
+    assertThat(loadModuleResult.isSuccessful()).isTrue();
+    assertThat(loadModuleResult.getMessage()).isEqualTo(true);
+  }
+
+  @Test
+  public void loadJarWithManifestAndClasspathAttributeInvalidClassName() {
+    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1WithManifest", "1.0")
+        .fromResourcePaths(MODULE1_PATH)
+        .build();
+
+    assertThat(moduleService.registerModule(geodeCommonDescriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.registerModule(geodeCommonsServiceDescriptor).isSuccessful()).isTrue();
+    assertThat(moduleService.registerModule(module1Descriptor).isSuccessful()).isTrue();
+    loadModuleAndAssert(module1Descriptor);
+
+    ModuleServiceResult<Map<String, Class<?>>> loadClassResult =
+        moduleService.loadClass(".ocm.this.should.not.Exist");
+    assertThat(loadClassResult.isSuccessful()).isTrue();
+    assertThat(loadClassResult.getMessage().size()).isEqualTo(0);
+  }
+
+  @Test
+  public void loadJarWithManifestWithInvalidClasspathLocation() {
+    ModuleDescriptor descriptor = new ModuleDescriptor.Builder("module5", "1.0")
+        .fromResourcePaths(MODULE5_PATH)
+        .build();
+
+    assertThat(moduleService.registerModule(descriptor).isSuccessful()).isTrue();
+
+    ModuleServiceResult<Boolean> loadModuleResult = moduleService.loadModule(descriptor);
+    assertThat(loadModuleResult.isSuccessful()).isFalse();
+    assertThat(loadModuleResult).isExactlyInstanceOf(Failure.class);
+
+    String[] errorMessageSnippet =
+        new String[] {"java.io.FileNotFoundException:", "java.nio.file.NoSuchFileException:"};
+    assertMessageContains(loadModuleResult.getErrorMessage(), errorMessageSnippet);
+    assertThat(loadModuleResult.getErrorMessage())
+        .contains("libs/invalidjar.jar");
+  }
+
+  private void assertMessageContains(String errorMessage, String[] errorMessageSnippet) {
+    AtomicBoolean containsString = new AtomicBoolean();
+    Arrays.stream(errorMessageSnippet)
+        .forEach(errorSnippet -> containsString.set(errorMessage.contains(errorMessage)));
+    assertThat(containsString.get()).isTrue();
+  }
+}
diff --git a/geode-modules/src/test/java/org/jboss/modules/GeodeJarModuleFinderTest.java b/geode-modules/src/test/java/org/jboss/modules/GeodeJarModuleFinderTest.java
new file mode 100644
index 0000000..99846a4
--- /dev/null
+++ b/geode-modules/src/test/java/org/jboss/modules/GeodeJarModuleFinderTest.java
@@ -0,0 +1,231 @@
+/*
+ * 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.jboss.modules;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.apache.logging.log4j.LogManager;
+import org.junit.Test;
+
+import org.apache.geode.services.module.ModuleDescriptor;
+
+public class GeodeJarModuleFinderTest {
+
+  private static final String MODULE1_PATH =
+      System.getProperty("user.dir") + "/../libs/module1WithManifest-1.0.jar";
+  private static final String MODULE2_PATH =
+      System.getProperty("user.dir") + "/../libs/module2WithManifest-1.0.jar";
+  private static final String MODULE3_PATH =
+      System.getProperty("user.dir") + "/../libs/module3WithManifest-1.0.jar";
+  private static final String MODULE4_PATH =
+      System.getProperty("user.dir") + "/../libs/module4WithManifest-1.0.jar";
+
+  private static final String GEODE_COMMONS_SERVICES_PATH =
+      System.getProperty("user.dir") + "/../libs/geode-common-services-1.14.0-build.0.jar";
+  private static final String GEODE_COMMONS_PATH =
+      System.getProperty("user.dir") + "/../libs/geode-common-1.14.0-build.0.jar";
+
+  @Test
+  public void findModuleSimpleJar() throws IOException, ModuleLoadException {
+    ModuleDescriptor moduleDescriptor =
+        new ModuleDescriptor.Builder("module1WithManifest", "1.0").fromResourcePaths(MODULE1_PATH)
+            .build();
+
+    ModuleFinder moduleFinder = new GeodeJarModuleFinder(LogManager.getLogger(), moduleDescriptor);
+    ConcreteModuleSpec moduleSpec = (ConcreteModuleSpec) moduleFinder
+        .findModule(moduleDescriptor.getName(), Module.getSystemModuleLoader());
+
+    assertThat(moduleSpec.getName()).isEqualTo(moduleDescriptor.getName());
+    assertThat(moduleSpec.getDependencies().length).isEqualTo(4);
+    String[] expectedDependencies = new String[] {"spring-core", "spring-jcl", "log4j-core",
+        "log4j-api", "jboss-modules", "module1WithManifest"};
+    ResourceLoaderSpec[] resourceLoaders = moduleSpec.getResourceLoaders();
+    assertThat(resourceLoaders.length).isEqualTo(expectedDependencies.length);
+    List<String> loadedResources = Arrays.stream(resourceLoaders)
+        .map(resourceLoaderSpec -> resourceLoaderSpec.getResourceLoader().getLocation().toString())
+        .collect(Collectors.toList());
+    for (String expectedDependency : expectedDependencies) {
+      boolean found = false;
+      for (String loadedResource : loadedResources) {
+        boolean contains = loadedResource.contains(expectedDependency);
+        if (contains) {
+          found = true;
+        }
+      }
+      assertThat(found).isTrue();
+    }
+  }
+
+  @Test
+  public void findModuleMultipleSourceJars() throws IOException, ModuleLoadException {
+    ModuleDescriptor moduleDescriptor =
+        new ModuleDescriptor.Builder("module1WithManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH, MODULE2_PATH)
+            .build();
+
+    ModuleFinder moduleFinder = new GeodeJarModuleFinder(LogManager.getLogger(), moduleDescriptor);
+    ConcreteModuleSpec moduleSpec = (ConcreteModuleSpec) moduleFinder
+        .findModule(moduleDescriptor.getName(), Module.getSystemModuleLoader());
+
+    assertThat(moduleSpec.getName()).isEqualTo(moduleDescriptor.getName());
+    // This contain duplicate entries for 'geode-common-services'. This is because the underlying
+    // moduleBuilder does
+    // check for duplicates
+    assertThat(moduleSpec.getDependencies().length).isEqualTo(5);
+    String[] expectedDependencies = new String[] {"spring-core", "spring-jcl", "log4j-core",
+        "log4j-api", "jboss-modules", "module1WithManifest", "module2WithManifest"};
+    assertModuleResourcesEqual(moduleSpec, expectedDependencies);
+  }
+
+  private void assertModuleResourcesEqual(ConcreteModuleSpec moduleSpec,
+      String[] expectedDependencies) {
+    Set<String> loadedResources = Arrays.stream(moduleSpec.getResourceLoaders())
+        .map(resourceLoaderSpec -> resourceLoaderSpec.getResourceLoader().getLocation().toString())
+        .collect(Collectors.toSet());
+    assertThat(loadedResources.size()).isEqualTo(expectedDependencies.length);
+    for (String expectedDependency : expectedDependencies) {
+      boolean found = false;
+      for (String loadedResource : loadedResources) {
+        boolean contains = loadedResource.contains(expectedDependency);
+        if (contains) {
+          found = true;
+        }
+      }
+      assertThat(found).isTrue();
+    }
+  }
+
+  @Test
+  public void findModuleJarWithDependencies() throws IOException, ModuleLoadException {
+    ModuleDescriptor moduleDescriptor =
+        new ModuleDescriptor.Builder("module1WithManifest", "1.0").fromResourcePaths(MODULE1_PATH)
+            .dependsOnModules("exampleModule")
+            .build();
+
+    ModuleFinder moduleFinder = new GeodeJarModuleFinder(LogManager.getLogger(), moduleDescriptor);
+    ConcreteModuleSpec moduleSpec = (ConcreteModuleSpec) moduleFinder
+        .findModule(moduleDescriptor.getName(), Module.getSystemModuleLoader());
+
+    assertThat(moduleSpec.getName()).isEqualTo(moduleDescriptor.getName());
+    assertThat(moduleSpec.getDependencies().length).isEqualTo(5);
+    String[] expectedDependencies = new String[] {"spring-core", "spring-jcl", "log4j-core",
+        "log4j-api", "jboss-modules", "module1WithManifest"};
+    assertModuleResourcesEqual(moduleSpec, expectedDependencies);
+  }
+
+  @Test
+  public void loadJarFile() throws IOException, ModuleLoadException {
+    ModuleDescriptor moduleDescriptor =
+        new ModuleDescriptor.Builder("module1WithManifest", "1.0").fromResourcePaths(MODULE1_PATH)
+            .build();
+
+    ModuleDescriptor geodeCommonsServiceDescriptor =
+        new ModuleDescriptor.Builder("geode-common-services-1.14.0-build.0")
+            .fromResourcePaths(GEODE_COMMONS_SERVICES_PATH)
+            .build();
+
+    ModuleDescriptor geodeCommonDescriptor =
+        new ModuleDescriptor.Builder("geode-common-1.14.0-build.0")
+            .fromResourcePaths(GEODE_COMMONS_PATH)
+            .build();
+
+    ModuleLoader moduleLoader = new TestModuleLoader(Module.getSystemModuleLoader(),
+        new ModuleFinder[] {
+            new GeodeJarModuleFinder(LogManager.getLogger(),
+                moduleDescriptor),
+            new GeodeJarModuleFinder(LogManager.getLogger(),
+                geodeCommonsServiceDescriptor),
+            new GeodeJarModuleFinder(LogManager.getLogger(),
+                geodeCommonDescriptor)
+        });
+    Module module = moduleLoader.loadModule(moduleDescriptor.getName());
+    assertThat(module).isNotNull();
+  }
+
+  @Test
+  public void loadMultipleJarFiles() throws IOException, ModuleLoadException {
+    ModuleDescriptor moduleDescriptor =
+        new ModuleDescriptor.Builder("module1WithManifest", "1.0")
+            .fromResourcePaths(MODULE1_PATH, MODULE2_PATH)
+            .build();
+
+    ModuleDescriptor geodeCommonsServiceDescriptor =
+        new ModuleDescriptor.Builder("geode-common-services-1.14.0-build.0")
+            .fromResourcePaths(GEODE_COMMONS_SERVICES_PATH)
+            .build();
+
+    ModuleDescriptor geodeCommonDescriptor =
+        new ModuleDescriptor.Builder("geode-common-1.14.0-build.0")
+            .fromResourcePaths(GEODE_COMMONS_PATH)
+            .build();
+
+    ModuleLoader moduleLoader = new TestModuleLoader(Module.getSystemModuleLoader(),
+        new ModuleFinder[] {
+            new GeodeJarModuleFinder(LogManager.getLogger(), moduleDescriptor),
+            new GeodeJarModuleFinder(LogManager.getLogger(), geodeCommonsServiceDescriptor),
+            new GeodeJarModuleFinder(LogManager.getLogger(), geodeCommonDescriptor)
+        });
+    Module module = moduleLoader.loadModule(moduleDescriptor.getName());
+    assertThat(module).isNotNull();
+  }
+
+  @Test
+  public void loadJarFileWithDependencies() throws IOException, ModuleLoadException {
+    ModuleDescriptor commonServices =
+        new ModuleDescriptor.Builder("geode-common-services", "1.14.0-build.0")
+            .fromResourcePaths(GEODE_COMMONS_SERVICES_PATH).build();
+
+    ModuleDescriptor geodeCommon = new ModuleDescriptor.Builder("geode-common", "1.14.0-build.0")
+        .fromResourcePaths(GEODE_COMMONS_PATH).build();
+
+    ModuleDescriptor module1Descriptor =
+        new ModuleDescriptor.Builder("module1WithManifest", "1.0").fromResourcePaths(MODULE1_PATH)
+            .build();
+
+    ModuleDescriptor module2Descriptor =
+        new ModuleDescriptor.Builder("module2", "1.0")
+            .fromResourcePaths(MODULE2_PATH)
+            .build();
+
+    ModuleLoader moduleLoader = new TestModuleLoader(Module.getSystemModuleLoader(),
+        new ModuleFinder[] {
+            new GeodeJarModuleFinder(LogManager.getLogger(), geodeCommon),
+            new GeodeJarModuleFinder(LogManager.getLogger(), commonServices),
+            new GeodeJarModuleFinder(LogManager.getLogger(),
+                module1Descriptor),
+            new GeodeJarModuleFinder(LogManager.getLogger(), module2Descriptor)
+        });
+
+    assertThat(moduleLoader.loadModule(geodeCommon.getName())).isNotNull();
+    assertThat(moduleLoader.loadModule(commonServices.getName())).isNotNull();
+    assertThat(moduleLoader.loadModule(module1Descriptor.getName())).isNotNull();
+    Module module = moduleLoader.loadModule(module2Descriptor.getName());
+    assertThat(module).isNotNull();
+  }
+
+  private static class TestModuleLoader extends DelegatingModuleLoader {
+
+    public TestModuleLoader(ModuleLoader delegate, ModuleFinder[] finders) {
+      super(delegate, finders);
+    }
+  }
+}
diff --git a/geode-modules/src/test/resources/expected-pom.xml b/geode-modules/src/test/resources/expected-pom.xml
index 50c2beb..62c7dae 100644
--- a/geode-modules/src/test/resources/expected-pom.xml
+++ b/geode-modules/src/test/resources/expected-pom.xml
@@ -19,7 +19,7 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>org.apache.geode</groupId>
   <artifactId>geode-modules</artifactId>
-  <version>1.13.0-SNAPSHOT</version>
+  <version>${version}</version>
   <name>Apache Geode</name>
   <description>Apache Geode provides a database-like consistency model, reliable transaction processing and a shared-nothing architecture to maintain very low latency performance with high concurrency processing</description>
   <url>http://geode.apache.org</url>
@@ -34,25 +34,9 @@
     <developerConnection>scm:git:https://github.com:apache/geode.git</developerConnection>
     <url>https://github.com/apache/geode</url>
   </scm>
-  <dependencyManagement>
-    <dependencies>
-      <dependency>
-        <groupId>org.apache.geode</groupId>
-        <artifactId>geode-all-bom</artifactId>
-        <version>1.13.0-SNAPSHOT</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-    </dependencies>
-  </dependencyManagement>
   <dependencies>
     <dependency>
       <groupId>org.apache.geode</groupId>
-      <artifactId>geode-common</artifactId>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.geode</groupId>
       <artifactId>geode-common-services</artifactId>
       <scope>compile</scope>
     </dependency>
@@ -62,16 +46,6 @@
       <scope>compile</scope>
     </dependency>
     <dependency>
-      <groupId>org.apache.geode</groupId>
-      <artifactId>geode-logging</artifactId>
-      <scope>runtime</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.geode</groupId>
-      <artifactId>geode-log4j</artifactId>
-      <scope>runtime</scope>
-    </dependency>
-    <dependency>
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-core</artifactId>
       <scope>runtime</scope>
diff --git a/geode-modules/src/testModules/module1/resources/META-INF/services/org.apache.geode.TestService b/geode-modules/src/testModules/module1/resources/META-INF/services/org.apache.geode.TestService
deleted file mode 100644
index 209c875..0000000
--- a/geode-modules/src/testModules/module1/resources/META-INF/services/org.apache.geode.TestService
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.geode.Module1
\ No newline at end of file
diff --git a/geode-modules/src/testModules/module1/java/org/apache/geode/Module1.java b/geode-modules/src/testModules/module1WithManifest/java/org/apache/geode/ModuleService1.java
similarity index 94%
copy from geode-modules/src/testModules/module1/java/org/apache/geode/Module1.java
copy to geode-modules/src/testModules/module1WithManifest/java/org/apache/geode/ModuleService1.java
index 0463781..05cd417 100644
--- a/geode-modules/src/testModules/module1/java/org/apache/geode/Module1.java
+++ b/geode-modules/src/testModules/module1WithManifest/java/org/apache/geode/ModuleService1.java
@@ -15,7 +15,7 @@
 
 package org.apache.geode;
 
-public class Module1 implements TestService {
+public class ModuleService1 implements TestService {
   @Override
   public String sayHello() {
     return "Hello from Module1!";
diff --git a/geode-modules/src/testModules/module1WithManifest/resources/META-INF/services/org.apache.geode.TestService b/geode-modules/src/testModules/module1WithManifest/resources/META-INF/services/org.apache.geode.TestService
new file mode 100644
index 0000000..51549ab
--- /dev/null
+++ b/geode-modules/src/testModules/module1WithManifest/resources/META-INF/services/org.apache.geode.TestService
@@ -0,0 +1 @@
+org.apache.geode.ModuleService1
\ No newline at end of file
diff --git a/geode-modules/src/testModules/module1/java/org/apache/geode/Module1.java b/geode-modules/src/testModules/module1WithoutManifest/java/org/apache/geode/ModuleService1.java
similarity index 94%
rename from geode-modules/src/testModules/module1/java/org/apache/geode/Module1.java
rename to geode-modules/src/testModules/module1WithoutManifest/java/org/apache/geode/ModuleService1.java
index 0463781..05cd417 100644
--- a/geode-modules/src/testModules/module1/java/org/apache/geode/Module1.java
+++ b/geode-modules/src/testModules/module1WithoutManifest/java/org/apache/geode/ModuleService1.java
@@ -15,7 +15,7 @@
 
 package org.apache.geode;
 
-public class Module1 implements TestService {
+public class ModuleService1 implements TestService {
   @Override
   public String sayHello() {
     return "Hello from Module1!";
diff --git a/geode-modules/src/testModules/module1WithoutManifest/resources/META-INF/services/org.apache.geode.TestService b/geode-modules/src/testModules/module1WithoutManifest/resources/META-INF/services/org.apache.geode.TestService
new file mode 100644
index 0000000..51549ab
--- /dev/null
+++ b/geode-modules/src/testModules/module1WithoutManifest/resources/META-INF/services/org.apache.geode.TestService
@@ -0,0 +1 @@
+org.apache.geode.ModuleService1
\ No newline at end of file
diff --git a/geode-modules/src/testModules/module2/resources/META-INF/services/org.apache.geode.TestService b/geode-modules/src/testModules/module2/resources/META-INF/services/org.apache.geode.TestService
deleted file mode 100644
index 6e0cde8..0000000
--- a/geode-modules/src/testModules/module2/resources/META-INF/services/org.apache.geode.TestService
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.geode.Module2
\ No newline at end of file
diff --git a/geode-modules/src/testModules/module2/java/org/apache/geode/Module2.java b/geode-modules/src/testModules/module2WithManifest/java/org/apache/geode/ModuleService2.java
similarity index 94%
copy from geode-modules/src/testModules/module2/java/org/apache/geode/Module2.java
copy to geode-modules/src/testModules/module2WithManifest/java/org/apache/geode/ModuleService2.java
index 1008bbd..241ce69 100644
--- a/geode-modules/src/testModules/module2/java/org/apache/geode/Module2.java
+++ b/geode-modules/src/testModules/module2WithManifest/java/org/apache/geode/ModuleService2.java
@@ -15,7 +15,7 @@
 
 package org.apache.geode;
 
-public class Module2 implements TestService {
+public class ModuleService2 implements TestService {
   @Override
   public String sayHello() {
     return "Hello from Module2!";
diff --git a/geode-modules/src/testModules/module2WithManifest/resources/META-INF/services/org.apache.geode.TestService b/geode-modules/src/testModules/module2WithManifest/resources/META-INF/services/org.apache.geode.TestService
new file mode 100644
index 0000000..33cc5d0
--- /dev/null
+++ b/geode-modules/src/testModules/module2WithManifest/resources/META-INF/services/org.apache.geode.TestService
@@ -0,0 +1 @@
+org.apache.geode.ModuleService2
\ No newline at end of file
diff --git a/geode-modules/src/testModules/module2/java/org/apache/geode/Module2.java b/geode-modules/src/testModules/module2WithoutManifest/java/org/apache/geode/ModuleService2.java
similarity index 94%
rename from geode-modules/src/testModules/module2/java/org/apache/geode/Module2.java
rename to geode-modules/src/testModules/module2WithoutManifest/java/org/apache/geode/ModuleService2.java
index 1008bbd..241ce69 100644
--- a/geode-modules/src/testModules/module2/java/org/apache/geode/Module2.java
+++ b/geode-modules/src/testModules/module2WithoutManifest/java/org/apache/geode/ModuleService2.java
@@ -15,7 +15,7 @@
 
 package org.apache.geode;
 
-public class Module2 implements TestService {
+public class ModuleService2 implements TestService {
   @Override
   public String sayHello() {
     return "Hello from Module2!";
diff --git a/geode-modules/src/testModules/module2WithoutManifest/resources/META-INF/services/org.apache.geode.TestService b/geode-modules/src/testModules/module2WithoutManifest/resources/META-INF/services/org.apache.geode.TestService
new file mode 100644
index 0000000..33cc5d0
--- /dev/null
+++ b/geode-modules/src/testModules/module2WithoutManifest/resources/META-INF/services/org.apache.geode.TestService
@@ -0,0 +1 @@
+org.apache.geode.ModuleService2
\ No newline at end of file
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
deleted file mode 100644
index e47bd26..0000000
--- a/geode-modules/src/testModules/module3/resources/META-INF/services/org.apache.geode.TestService
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.geode.Module3
\ No newline at end of file
diff --git a/geode-modules/src/testModules/module3/java/org/apache/geode/Module3.java b/geode-modules/src/testModules/module3WithManifest/java/org/apache/geode/ModuleService3.java
similarity index 94%
copy from geode-modules/src/testModules/module3/java/org/apache/geode/Module3.java
copy to geode-modules/src/testModules/module3WithManifest/java/org/apache/geode/ModuleService3.java
index 34bfbdd..600a3fe 100644
--- a/geode-modules/src/testModules/module3/java/org/apache/geode/Module3.java
+++ b/geode-modules/src/testModules/module3WithManifest/java/org/apache/geode/ModuleService3.java
@@ -15,7 +15,7 @@
 
 package org.apache.geode;
 
-public class Module3 implements TestService {
+public class ModuleService3 implements TestService {
   @Override
   public String sayHello() {
     return "Hello from Module3!";
diff --git a/geode-modules/src/testModules/module3WithManifest/resources/META-INF/services/org.apache.geode.TestService b/geode-modules/src/testModules/module3WithManifest/resources/META-INF/services/org.apache.geode.TestService
new file mode 100644
index 0000000..7d46531
--- /dev/null
+++ b/geode-modules/src/testModules/module3WithManifest/resources/META-INF/services/org.apache.geode.TestService
@@ -0,0 +1 @@
+org.apache.geode.ModuleService3
\ No newline at end of file
diff --git a/geode-modules/src/testModules/module3/java/org/apache/geode/Module3.java b/geode-modules/src/testModules/module3WithoutManifest/java/org/apache/geode/ModuleService3.java
similarity index 94%
rename from geode-modules/src/testModules/module3/java/org/apache/geode/Module3.java
rename to geode-modules/src/testModules/module3WithoutManifest/java/org/apache/geode/ModuleService3.java
index 34bfbdd..600a3fe 100644
--- a/geode-modules/src/testModules/module3/java/org/apache/geode/Module3.java
+++ b/geode-modules/src/testModules/module3WithoutManifest/java/org/apache/geode/ModuleService3.java
@@ -15,7 +15,7 @@
 
 package org.apache.geode;
 
-public class Module3 implements TestService {
+public class ModuleService3 implements TestService {
   @Override
   public String sayHello() {
     return "Hello from Module3!";
diff --git a/geode-modules/src/testModules/module3WithoutManifest/resources/META-INF/services/org.apache.geode.TestService b/geode-modules/src/testModules/module3WithoutManifest/resources/META-INF/services/org.apache.geode.TestService
new file mode 100644
index 0000000..7d46531
--- /dev/null
+++ b/geode-modules/src/testModules/module3WithoutManifest/resources/META-INF/services/org.apache.geode.TestService
@@ -0,0 +1 @@
+org.apache.geode.ModuleService3
\ No newline at end of file
diff --git a/geode-modules/src/testModules/module4/java/org/apache/geode/Module4.java b/geode-modules/src/testModules/module4WithManifest/java/org/apache/geode/ModuleService4.java
similarity index 96%
copy from geode-modules/src/testModules/module4/java/org/apache/geode/Module4.java
copy to geode-modules/src/testModules/module4WithManifest/java/org/apache/geode/ModuleService4.java
index c494905..91a9887 100644
--- a/geode-modules/src/testModules/module4/java/org/apache/geode/Module4.java
+++ b/geode-modules/src/testModules/module4WithManifest/java/org/apache/geode/ModuleService4.java
@@ -15,5 +15,5 @@
 
 package org.apache.geode;
 
-public class Module4 {
+public class ModuleService4 {
 }
diff --git a/geode-modules/src/testModules/module4/java/org/apache/geode/Module4.java b/geode-modules/src/testModules/module4WithoutManifest/java/org/apache/geode/ModuleService4.java
similarity index 96%
copy from geode-modules/src/testModules/module4/java/org/apache/geode/Module4.java
copy to geode-modules/src/testModules/module4WithoutManifest/java/org/apache/geode/ModuleService4.java
index c494905..91a9887 100644
--- a/geode-modules/src/testModules/module4/java/org/apache/geode/Module4.java
+++ b/geode-modules/src/testModules/module4WithoutManifest/java/org/apache/geode/ModuleService4.java
@@ -15,5 +15,5 @@
 
 package org.apache.geode;
 
-public class Module4 {
+public class ModuleService4 {
 }
diff --git a/geode-modules/src/testModules/module4/java/org/apache/geode/Module4.java b/geode-modules/src/testModules/module5WithManifest/java/org/apache/geode/ModuleService5.java
similarity index 96%
rename from geode-modules/src/testModules/module4/java/org/apache/geode/Module4.java
rename to geode-modules/src/testModules/module5WithManifest/java/org/apache/geode/ModuleService5.java
index c494905..f155862 100644
--- a/geode-modules/src/testModules/module4/java/org/apache/geode/Module4.java
+++ b/geode-modules/src/testModules/module5WithManifest/java/org/apache/geode/ModuleService5.java
@@ -15,5 +15,5 @@
 
 package org.apache.geode;
 
-public class Module4 {
+public class ModuleService5 {
 }


[geode] 03/08: GEODE-8043 - Create JBossModuleService and implement loadModule. (#5081)

Posted by ud...@apache.org.
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 700f9d469e133af4ede71698ade30b1d449e8ed3
Author: Udo Kohlmeyer <uk...@pivtotal.io>
AuthorDate: Tue May 19 09:20:46 2020 -0700

    GEODE-8043 - Create JBossModuleService and implement loadModule. (#5081)
---
 .../src/test/resources/expected-pom.xml            |  18 +
 .../gradle/plugins/DependencyConstraints.groovy    |   3 +
 geode-assembly/build.gradle                        |   2 +
 .../integrationTest/resources/assembly_content.txt |  22 ++
 .../resources/dependency_classpath.txt             |  27 +-
 .../integrationTest/resources/expected_jars.txt    |   1 +
 geode-common-services/build.gradle                 |  33 ++
 .../geode/services/module/ModuleDescriptor.java    | 100 +++++
 .../geode/services/module/ModuleService.java       |  36 ++
 .../src/test/resources/expected-pom.xml            |  60 +++
 geode-modules/build.gradle                         |  97 +++++
 .../services/module/impl/GeodeModuleLoader.java    |  53 +++
 .../services/module/impl/JBossModuleService.java   | 115 ++++++
 .../module/impl/JBossModuleServiceTest.java        | 402 +++++++++++++++++++++
 geode-modules/src/test/resources/expected-pom.xml  |  80 ++++
 .../module1/java/org/apache/geode/Module1.java     |  19 +
 .../module2/java/org.apache.geode/Module2.java     |  19 +
 .../module3/java/org/apache/geode/Module3.java     |  19 +
 .../module4/java/org/apache/geode/Module4.java     |  19 +
 settings.gradle                                    |   2 +
 20 files changed, 1115 insertions(+), 12 deletions(-)

diff --git a/boms/geode-all-bom/src/test/resources/expected-pom.xml b/boms/geode-all-bom/src/test/resources/expected-pom.xml
index fab3870..02cc94e 100644
--- a/boms/geode-all-bom/src/test/resources/expected-pom.xml
+++ b/boms/geode-all-bom/src/test/resources/expected-pom.xml
@@ -464,6 +464,12 @@
         <scope>compile</scope>
       </dependency>
       <dependency>
+        <groupId>org.jboss.modules</groupId>
+        <artifactId>jboss-modules</artifactId>
+        <version>1.10.1.Final</version>
+        <scope>compile</scope>
+      </dependency>
+      <dependency>
         <groupId>org.jgroups</groupId>
         <artifactId>jgroups</artifactId>
         <version>3.6.14.Final</version>
@@ -891,6 +897,12 @@
       </dependency>
       <dependency>
         <groupId>org.apache.geode</groupId>
+        <artifactId>geode-common-services</artifactId>
+        <version>${version}</version>
+        <scope>compile</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
         <artifactId>geode-concurrency-test</artifactId>
         <version>${version}</version>
         <scope>compile</scope>
@@ -981,6 +993,12 @@
       </dependency>
       <dependency>
         <groupId>org.apache.geode</groupId>
+        <artifactId>geode-modules</artifactId>
+        <version>${version}</version>
+        <scope>compile</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
         <artifactId>geode-old-client-support</artifactId>
         <version>${version}</version>
         <scope>compile</scope>
diff --git a/buildSrc/src/main/groovy/org/apache/geode/gradle/plugins/DependencyConstraints.groovy b/buildSrc/src/main/groovy/org/apache/geode/gradle/plugins/DependencyConstraints.groovy
index 2420610..ce8c4b1 100644
--- a/buildSrc/src/main/groovy/org/apache/geode/gradle/plugins/DependencyConstraints.groovy
+++ b/buildSrc/src/main/groovy/org/apache/geode/gradle/plugins/DependencyConstraints.groovy
@@ -31,6 +31,8 @@ class DependencyConstraints implements Plugin<Project> {
     Map<String,String> deps = new HashMap<>()
     // These versions are consumed beyond the scope of source set dependencies.
 
+    deps.put("jboss-modules.version", "1.10.1.Final")
+
     // These version numbers are consumed by :geode-modules-assembly:distAppServer filtering
     // Some of these are referenced below as well
     deps.put("antlr.version", "2.7.7")
@@ -155,6 +157,7 @@ class DependencyConstraints implements Plugin<Project> {
         api(group: 'org.eclipse.persistence', name: 'javax.persistence', version: '2.2.1')
         api(group: 'org.httpunit', name: 'httpunit', version: '1.7.3')
         api(group: 'org.iq80.snappy', name: 'snappy', version: '0.4')
+        api(group: 'org.jboss.modules', name: 'jboss-modules', version: get('jboss-modules.version'))
         api(group: 'org.jgroups', name: 'jgroups', version: get('jgroups.version'))
         api(group: 'org.mockito', name: 'mockito-core', version: '3.3.3')
         api(group: 'org.mortbay.jetty', name: 'servlet-api', version: '3.0.20100224')
diff --git a/geode-assembly/build.gradle b/geode-assembly/build.gradle
index 96cc137..f40a908 100755
--- a/geode-assembly/build.gradle
+++ b/geode-assembly/build.gradle
@@ -28,6 +28,7 @@ import java.nio.file.Paths
 // This list is used in a loop to defined the /lib copySpec
 def dependentProjectNames = [
   ':geode-common',
+  ':geode-common-services',
   ':geode-connectors',
   ':geode-core',
   ':geode-cq',
@@ -36,6 +37,7 @@ def dependentProjectNames = [
   ':geode-logging',
   ':geode-lucene',
   ':geode-memcached',
+  ':geode-modules',
   ':geode-old-client-support',
   ':geode-protobuf',
   ':geode-protobuf-messages',
diff --git a/geode-assembly/src/integrationTest/resources/assembly_content.txt b/geode-assembly/src/integrationTest/resources/assembly_content.txt
index 7173275..9c4051a 100644
--- a/geode-assembly/src/integrationTest/resources/assembly_content.txt
+++ b/geode-assembly/src/integrationTest/resources/assembly_content.txt
@@ -966,6 +966,25 @@ javadoc/org/apache/geode/security/SecurityManager.html
 javadoc/org/apache/geode/security/package-frame.html
 javadoc/org/apache/geode/security/package-summary.html
 javadoc/org/apache/geode/security/package-tree.html
+javadoc/org/apache/geode/services/bootstrapping/BootstrappingService.html
+javadoc/org/apache/geode/services/bootstrapping/package-frame.html
+javadoc/org/apache/geode/services/bootstrapping/package-summary.html
+javadoc/org/apache/geode/services/bootstrapping/package-tree.html
+javadoc/org/apache/geode/services/management/ManagementService.html
+javadoc/org/apache/geode/services/management/package-frame.html
+javadoc/org/apache/geode/services/management/package-summary.html
+javadoc/org/apache/geode/services/management/package-tree.html
+javadoc/org/apache/geode/services/module/ModuleDescriptor.Builder.html
+javadoc/org/apache/geode/services/module/ModuleDescriptor.html
+javadoc/org/apache/geode/services/module/ModuleService.html
+javadoc/org/apache/geode/services/module/impl/GeodeModuleLoader.html
+javadoc/org/apache/geode/services/module/impl/JBossModuleService.html
+javadoc/org/apache/geode/services/module/impl/package-frame.html
+javadoc/org/apache/geode/services/module/impl/package-summary.html
+javadoc/org/apache/geode/services/module/impl/package-tree.html
+javadoc/org/apache/geode/services/module/package-frame.html
+javadoc/org/apache/geode/services/module/package-summary.html
+javadoc/org/apache/geode/services/module/package-tree.html
 javadoc/overview-frame.html
 javadoc/overview-summary.html
 javadoc/overview-tree.html
@@ -991,6 +1010,7 @@ lib/fastutil-8.3.1.jar
 lib/findbugs-annotations-1.3.9-1.jar
 lib/geo-0.7.7.jar
 lib/geode-common-0.0.0.jar
+lib/geode-common-services-0.0.0.jar
 lib/geode-connectors-0.0.0.jar
 lib/geode-core-0.0.0.jar
 lib/geode-cq-0.0.0.jar
@@ -1004,6 +1024,7 @@ lib/geode-lucene-0.0.0.jar
 lib/geode-management-0.0.0.jar
 lib/geode-membership-0.0.0.jar
 lib/geode-memcached-0.0.0.jar
+lib/geode-modules-0.0.0.jar
 lib/geode-old-client-support-0.0.0.jar
 lib/geode-protobuf-0.0.0.jar
 lib/geode-protobuf-messages-0.0.0.jar
@@ -1028,6 +1049,7 @@ lib/javax.servlet-api-3.1.0.jar
 lib/javax.transaction-api-1.3.jar
 lib/jaxb-api-2.3.1.jar
 lib/jaxb-impl-2.3.2.jar
+lib/jboss-modules-1.10.1.Final.jar
 lib/jetty-http-9.4.21.v20190926.jar
 lib/jetty-io-9.4.21.v20190926.jar
 lib/jetty-security-9.4.21.v20190926.jar
diff --git a/geode-assembly/src/integrationTest/resources/dependency_classpath.txt b/geode-assembly/src/integrationTest/resources/dependency_classpath.txt
index a12a84b..0ef68c7 100644
--- a/geode-assembly/src/integrationTest/resources/dependency_classpath.txt
+++ b/geode-assembly/src/integrationTest/resources/dependency_classpath.txt
@@ -1,4 +1,5 @@
 geode-common-0.0.0.jar
+geode-common-services-0.0.0.jar
 geode-connectors-0.0.0.jar
 geode-core-0.0.0.jar
 geode-cq-0.0.0.jar
@@ -6,8 +7,8 @@ geode-gfsh-0.0.0.jar
 geode-log4j-0.0.0.jar
 geode-logging-0.0.0.jar
 geode-lucene-0.0.0.jar
-geode-management-0.0.0.jar
 geode-memcached-0.0.0.jar
+geode-modules-0.0.0.jar
 geode-old-client-support-0.0.0.jar
 geode-protobuf-0.0.0.jar
 geode-protobuf-messages-0.0.0.jar
@@ -16,22 +17,15 @@ geode-redis-0.0.0.jar
 geode-serialization-0.0.0.jar
 geode-tcp-server-0.0.0.jar
 geode-wan-0.0.0.jar
+geode-management-0.0.0.jar
 jackson-databind-2.10.1.jar
 jackson-annotations-2.10.1.jar
 jackson-core-2.10.1.jar
 geode-membership-0.0.0.jar
 geode-http-service-0.0.0.jar
 geode-unsafe-0.0.0.jar
-httpclient-4.5.12.jar
-httpcore-4.4.13.jar
-HikariCP-3.4.2.jar
-commons-lang3-3.10.jar
-jaxb-api-2.3.1.jar
-log4j-jcl-2.13.1.jar
-log4j-api-2.13.1.jar
-spring-shell-1.2.0.RELEASE.jar
-rmiio-2.1.2.jar
 antlr-2.7.7.jar
+rmiio-2.1.2.jar
 javax.activation-1.2.0.jar
 istack-commons-runtime-3.0.11.jar
 jaxb-impl-2.3.2.jar
@@ -39,6 +33,7 @@ commons-validator-1.6.jar
 shiro-core-1.5.3.jar
 shiro-config-ogdl-1.5.3.jar
 commons-beanutils-1.9.4.jar
+httpclient-4.5.12.jar
 commons-codec-1.14.jar
 commons-collections-3.2.2.jar
 commons-io-2.6.jar
@@ -53,9 +48,12 @@ jetty-servlet-9.4.21.v20190926.jar
 jetty-security-9.4.21.v20190926.jar
 jetty-server-9.4.21.v20190926.jar
 javax.servlet-api-3.1.0.jar
+jaxb-api-2.3.1.jar
 jna-platform-5.5.0.jar
 jna-5.5.0.jar
 jopt-simple-5.0.4.jar
+commons-lang3-3.10.jar
+httpcore-4.4.13.jar
 snappy-0.4.jar
 jgroups-3.6.14.Final.jar
 shiro-cache-1.5.3.jar
@@ -66,17 +64,21 @@ shiro-event-1.5.3.jar
 shiro-crypto-core-1.5.3.jar
 shiro-lang-1.5.3.jar
 slf4j-api-1.7.30.jar
+log4j-api-2.13.1.jar
 spring-core-5.2.5.RELEASE.jar
-javax.activation-api-1.2.0.jar
-jline-2.12.jar
 HdrHistogram-2.1.12.jar
 LatencyUtils-2.0.3.jar
 javax.transaction-api-1.3.jar
+javax.activation-api-1.2.0.jar
 spring-jcl-5.2.5.RELEASE.jar
 jetty-http-9.4.21.v20190926.jar
 jetty-io-9.4.21.v20190926.jar
 jetty-xml-9.4.21.v20190926.jar
 jetty-util-9.4.21.v20190926.jar
+HikariCP-3.4.2.jar
+log4j-jcl-2.13.1.jar
+spring-shell-1.2.0.RELEASE.jar
+jline-2.12.jar
 log4j-slf4j-impl-2.13.1.jar
 log4j-core-2.13.1.jar
 log4j-jul-2.13.1.jar
@@ -85,6 +87,7 @@ lucene-analyzers-common-6.6.6.jar
 lucene-queryparser-6.6.6.jar
 lucene-core-6.6.6.jar
 lucene-queries-6.6.6.jar
+jboss-modules-1.10.1.Final.jar
 protobuf-java-3.11.4.jar
 geo-0.7.7.jar
 netty-all-4.1.48.Final.jar
diff --git a/geode-assembly/src/integrationTest/resources/expected_jars.txt b/geode-assembly/src/integrationTest/resources/expected_jars.txt
index c116f7c..131d9a1 100644
--- a/geode-assembly/src/integrationTest/resources/expected_jars.txt
+++ b/geode-assembly/src/integrationTest/resources/expected_jars.txt
@@ -44,6 +44,7 @@ javax.servlet-api
 javax.transaction-api
 jaxb-api
 jaxb-impl
+jboss-modules
 jcip-annotations
 jetty-http
 jetty-io
diff --git a/geode-common-services/build.gradle b/geode-common-services/build.gradle
new file mode 100644
index 0000000..da983cf
--- /dev/null
+++ b/geode-common-services/build.gradle
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+apply from: "${rootDir}/${scriptDir}/standard-subproject-configuration.gradle"
+
+apply from: "${project.projectDir}/../gradle/publish-java.gradle"
+apply from: "${project.projectDir}/../gradle/warnings.gradle"
+
+repositories {
+    mavenCentral()
+}
+
+dependencies {
+    compile(platform(project(':boms:geode-all-bom')))
+
+    compile(project(':geode-common'))
+
+    compile(project(':geode-core'))
+}
diff --git a/geode-common-services/src/main/java/org/apache/geode/services/module/ModuleDescriptor.java b/geode-common-services/src/main/java/org/apache/geode/services/module/ModuleDescriptor.java
new file mode 100644
index 0000000..3b84130
--- /dev/null
+++ b/geode-common-services/src/main/java/org/apache/geode/services/module/ModuleDescriptor.java
@@ -0,0 +1,100 @@
+/*
+ * 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.geode.services.module;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.geode.annotations.Experimental;
+
+/**
+ * Holds information to describe a classloader-isolated module including how to create it.
+ *
+ * @see Builder
+ * @see ModuleService
+ *
+ * @since Geode 1.13.0
+ */
+@Experimental
+public class ModuleDescriptor {
+
+  private String name;
+
+  private String version;
+
+  private List<String> sources;
+
+  private List<String> dependencies;
+
+  private ModuleDescriptor(String name, String version, List<String> sources,
+      List<String> dependencies) {
+    this.name = name;
+    this.version = version;
+    this.sources = sources;
+    this.dependencies = dependencies;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public String getVersion() {
+    return version;
+  }
+
+  public List<String> getSources() {
+    return sources;
+  }
+
+  public List<String> getDependedOnModules() {
+    return dependencies;
+  }
+
+  public String getVersionedName() {
+    return name + ":" + version;
+  }
+
+  /**
+   * A Builder used to construct a {@link ModuleDescriptor}
+   */
+  public static class Builder {
+
+    private final String name;
+    private final String version;
+    private List<String> dependencies = Collections.emptyList();
+    private List<String> sources = Collections.emptyList();
+
+    public Builder(String name, String version) {
+      this.name = name;
+      this.version = version;
+    }
+
+    public Builder fromSources(String... sources) {
+      this.sources = Arrays.asList(sources);
+      return this;
+    }
+
+    public Builder dependsOnModules(String... dependencies) {
+      this.dependencies = Arrays.asList(dependencies);
+      return this;
+    }
+
+    public ModuleDescriptor build() {
+      return new ModuleDescriptor(name, version, sources, dependencies);
+    }
+  }
+}
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
new file mode 100644
index 0000000..cd295c0
--- /dev/null
+++ b/geode-common-services/src/main/java/org/apache/geode/services/module/ModuleService.java
@@ -0,0 +1,36 @@
+/*
+ * 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.geode.services.module;
+
+import org.apache.geode.annotations.Experimental;
+
+/**
+ * Loads and unloads modules and services in a classloader-isolated manner.
+ *
+ * @since Geode 1.13.0
+ */
+@Experimental
+public interface ModuleService {
+
+  /**
+   * Loads a module from a resource.
+   *
+   * @param moduleDescriptor description of the module to be loaded and information necessary to
+   *        load it.
+   * @return true on success, false if the module could not be loaded.
+   */
+  boolean loadModule(ModuleDescriptor moduleDescriptor);
+}
diff --git a/geode-common-services/src/test/resources/expected-pom.xml b/geode-common-services/src/test/resources/expected-pom.xml
new file mode 100644
index 0000000..26f1cdd
--- /dev/null
+++ b/geode-common-services/src/test/resources/expected-pom.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <!--
+  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.
+  -->
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.geode</groupId>
+  <artifactId>geode-common-services</artifactId>
+  <version>1.13.0-SNAPSHOT</version>
+  <name>Apache Geode</name>
+  <description>Apache Geode provides a database-like consistency model, reliable transaction processing and a shared-nothing architecture to maintain very low latency performance with high concurrency processing</description>
+  <url>http://geode.apache.org</url>
+  <licenses>
+    <license>
+      <name>The Apache Software License, Version 2.0</name>
+      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+    </license>
+  </licenses>
+  <scm>
+    <connection>scm:git:https://github.com:apache/geode.git</connection>
+    <developerConnection>scm:git:https://github.com:apache/geode.git</developerConnection>
+    <url>https://github.com/apache/geode</url>
+  </scm>
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
+        <artifactId>geode-all-bom</artifactId>
+        <version>1.13.0-SNAPSHOT</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.geode</groupId>
+      <artifactId>geode-common</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.geode</groupId>
+      <artifactId>geode-core</artifactId>
+      <scope>compile</scope>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/geode-modules/build.gradle b/geode-modules/build.gradle
new file mode 100644
index 0000000..319c0bd
--- /dev/null
+++ b/geode-modules/build.gradle
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ */
+
+apply from: "${rootDir}/${scriptDir}/standard-subproject-configuration.gradle"
+
+apply from: "${project.projectDir}/../gradle/publish-java.gradle"
+apply from: "${project.projectDir}/../gradle/warnings.gradle"
+
+sourceSets {
+    module1 {
+        java.srcDir "src/testModules/module1/java"
+        resources.srcDir "src/testModules/module1/resources"
+        compileClasspath += configurations.compileClasspath
+        runtimeClasspath += configurations.runtimeClasspath
+    }
+    module2 {
+        java.srcDir "src/testModules/module2/java"
+        resources.srcDir "src/testModules/module2/resources"
+        compileClasspath += configurations.compileClasspath
+        runtimeClasspath += configurations.runtimeClasspath
+    }
+    module3 {
+        java.srcDir "src/testModules/module3/java"
+        resources.srcDir "src/testModules/module3/resources"
+        compileClasspath += configurations.compileClasspath
+        runtimeClasspath += configurations.runtimeClasspath
+    }
+    module4 {
+        java.srcDir "src/testModules/module4/java"
+        resources.srcDir "src/testModules/module4/resources"
+        compileClasspath += configurations.compileClasspath
+        runtimeClasspath += configurations.runtimeClasspath
+    }
+}
+
+task module1Jar(type: Jar, dependsOn: classes) {
+    description 'Assembles the jar archive that contains the module1 classes'
+    from sourceSets.module1.output
+    archiveName 'module1.jar'
+}
+
+task module2Jar(type: Jar, dependsOn: classes) {
+    description 'Assembles the jar archive that contains the module2 classes'
+    from sourceSets.module2.output
+    archiveName 'module2.jar'
+}
+
+task module3Jar(type: Jar, dependsOn: classes) {
+    description 'Assembles the jar archive that contains the module3 classes'
+    from sourceSets.module3.output
+    archiveName 'module3.jar'
+}
+
+task module4Jar(type: Jar, dependsOn: classes) {
+    description 'Assembles the jar archive that contains the module4 classes'
+    from sourceSets.module4.output
+    archiveName 'module4.jar'
+}
+
+tasks.test.dependsOn("module1Jar")
+tasks.test.dependsOn("module2Jar")
+tasks.test.dependsOn("module3Jar")
+tasks.test.dependsOn("module4Jar")
+
+repositories {
+    mavenCentral()
+}
+
+dependencies {
+    testCompile(group: 'junit', name: 'junit', version: '4.12')
+    testImplementation('org.assertj:assertj-core')
+
+    compile(platform(project(':boms:geode-all-bom')))
+
+    compile(project(':geode-common'))
+    implementation(project(':geode-logging'))
+    implementation(project(':geode-log4j'))
+
+    compile(project(':geode-common-services'))
+
+    implementation('org.apache.logging.log4j:log4j-core')
+    compile('org.jboss.modules:jboss-modules')
+}
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
new file mode 100644
index 0000000..913df0c
--- /dev/null
+++ b/geode-modules/src/main/java/org/apache/geode/services/module/impl/GeodeModuleLoader.java
@@ -0,0 +1,53 @@
+/*
+ * 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.geode.services.module.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jboss.modules.DelegatingModuleLoader;
+import org.jboss.modules.Module;
+import org.jboss.modules.ModuleLoadException;
+import org.jboss.modules.ModuleLoader;
+import org.jboss.modules.ModuleSpec;
+
+import org.apache.geode.annotations.Experimental;
+
+/**
+ * {@link ModuleLoader} for use by {@link JBossModuleService}.
+ */
+@Experimental
+public class GeodeModuleLoader extends DelegatingModuleLoader {
+  private Map<String, ModuleSpec> moduleSpecs = new HashMap<>();
+
+  public GeodeModuleLoader() {
+    super(Module.getSystemModuleLoader(), ModuleLoader.NO_FINDERS);
+  }
+
+  public void addModuleSpec(ModuleSpec moduleSpec) {
+    moduleSpecs.put(moduleSpec.getName(), moduleSpec);
+  }
+
+  @Override
+  protected ModuleSpec findModule(String name) throws ModuleLoadException {
+    ModuleSpec moduleSpec = moduleSpecs.get(name);
+    if (moduleSpec == null) {
+      throw new ModuleLoadException(
+          String.format("ModuleSpec for Module %s could not be found", name));
+    }
+    return moduleSpecs.get(name);
+  }
+}
diff --git a/geode-modules/src/main/java/org/apache/geode/services/module/impl/JBossModuleService.java b/geode-modules/src/main/java/org/apache/geode/services/module/impl/JBossModuleService.java
new file mode 100644
index 0000000..9715709
--- /dev/null
+++ b/geode-modules/src/main/java/org/apache/geode/services/module/impl/JBossModuleService.java
@@ -0,0 +1,115 @@
+/*
+ * 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.geode.services.module.impl;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.jar.JarFile;
+
+import org.apache.logging.log4j.Logger;
+import org.jboss.modules.LocalDependencySpecBuilder;
+import org.jboss.modules.Module;
+import org.jboss.modules.ModuleDependencySpecBuilder;
+import org.jboss.modules.ModuleLoadException;
+import org.jboss.modules.ModuleSpec;
+import org.jboss.modules.ResourceLoader;
+import org.jboss.modules.ResourceLoaderSpec;
+import org.jboss.modules.ResourceLoaders;
+import org.jboss.modules.Version;
+
+import org.apache.geode.annotations.Experimental;
+import org.apache.geode.logging.internal.log4j.api.LogService;
+import org.apache.geode.services.module.ModuleDescriptor;
+import org.apache.geode.services.module.ModuleService;
+
+/**
+ * Implementation of {@link ModuleService} using JBoss-Modules.
+ */
+@Experimental
+public class JBossModuleService implements ModuleService {
+
+  private final Map<String, Module> modules = new HashMap<>();
+
+  private final GeodeModuleLoader moduleLoader = new GeodeModuleLoader();
+
+  private final Logger logger;
+
+  public JBossModuleService() {
+    this(LogService.getLogger());
+  }
+
+  public JBossModuleService(Logger logger) {
+    this.logger = logger;
+  }
+
+  public Module getModule(String name) {
+    return modules.get(name);
+  }
+
+  @Override
+  public boolean loadModule(ModuleDescriptor moduleDescriptor) {
+    logger.debug(String.format("Beginning to load module %s", moduleDescriptor.getVersionedName()));
+
+    if (modules.containsKey(moduleDescriptor.getVersionedName())) {
+      logger
+          .warn(String.format("Module %s is already loaded.", moduleDescriptor.getVersionedName()));
+      return false;
+    }
+
+    ModuleSpec.Builder builder = ModuleSpec.build(moduleDescriptor.getVersionedName());
+    builder.setVersion(Version.parse(moduleDescriptor.getVersion()));
+    builder.addDependency(new LocalDependencySpecBuilder()
+        .setImportServices(true)
+        .setExport(true)
+        .build());
+
+    moduleDescriptor.getDependedOnModules().forEach(dependency -> {
+      logger.debug(String.format("Adding dependency on module %s", dependency));
+      builder.addDependency(new ModuleDependencySpecBuilder()
+          .setName(dependency)
+          .build());
+    });
+
+    try {
+      for (String source : moduleDescriptor.getSources()) {
+        logger.debug(String.format("Adding resource %s to module", source));
+        ResourceLoader resourceLoader =
+            ResourceLoaders.createJarResourceLoader(new JarFile(source));
+        builder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec(resourceLoader));
+      }
+    } catch (IOException e) {
+      logger.error(e);
+      return false;
+    }
+
+    ModuleSpec moduleSpec = builder.create();
+    moduleLoader.addModuleSpec(moduleSpec);
+
+    try {
+      modules.put(moduleDescriptor.getVersionedName(),
+          moduleLoader.loadModule(moduleSpec.getName()));
+    } catch (ModuleLoadException e) {
+      logger.error(e);
+      return false;
+    }
+
+    logger
+        .debug(String.format("Module %s successfully loaded", moduleDescriptor.getVersionedName()));
+
+    return true;
+  }
+}
diff --git a/geode-modules/src/test/java/org/apache/geode/services/module/impl/JBossModuleServiceTest.java b/geode-modules/src/test/java/org/apache/geode/services/module/impl/JBossModuleServiceTest.java
new file mode 100644
index 0000000..bca62af
--- /dev/null
+++ b/geode-modules/src/test/java/org/apache/geode/services/module/impl/JBossModuleServiceTest.java
@@ -0,0 +1,402 @@
+/*
+ * 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.geode.services.module.impl;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import org.jboss.modules.Module;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.apache.geode.services.module.ModuleDescriptor;
+
+public class JBossModuleServiceTest {
+
+  private static final String MODULE1_PATH =
+      System.getProperty("user.dir") + "/../libs/module1.jar";
+  private static final String MODULE2_PATH =
+      System.getProperty("user.dir") + "/../libs/module2.jar";
+  private static final String MODULE3_PATH =
+      System.getProperty("user.dir") + "/../libs/module3.jar";
+  private static final String MODULE4_PATH =
+      System.getProperty("user.dir") + "/../libs/module4.jar";
+
+  private JBossModuleService moduleService;
+
+  @Before
+  public void setup() {
+    moduleService = new JBossModuleService();
+  }
+
+  @After
+  public void teardown() {
+    moduleService = null;
+  }
+
+  @Test
+  public void modulesNotAccessibleFromSystemClassloaderNoModulesLoaded() {
+    assertThatThrownBy(() -> {
+      this.getClass().getClassLoader().loadClass("org.apache.geode.Module1");
+    }).isInstanceOf(ClassNotFoundException.class);
+
+    assertThatThrownBy(() -> {
+      this.getClass().getClassLoader().loadClass("org.apache.geode.Module2");
+    }).isInstanceOf(ClassNotFoundException.class);
+  }
+
+  @Test
+  public void modulesNotAccessibleFromSystemClassloaderWithModulesLoaded() {
+    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
+        .fromSources(MODULE1_PATH)
+        .build();
+    ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module2", "1.0")
+        .fromSources(MODULE2_PATH)
+        .build();
+    moduleService.loadModule(module1Descriptor);
+    moduleService.loadModule(module2Descriptor);
+
+    assertThatThrownBy(() -> {
+      this.getClass().getClassLoader().loadClass("org.apache.geode.Module1");
+    }).isInstanceOf(ClassNotFoundException.class);
+
+    assertThatThrownBy(() -> {
+      this.getClass().getClassLoader().loadClass("org.apache.geode.Module2");
+    }).isInstanceOf(ClassNotFoundException.class);
+  }
+
+  @Test
+  public void loadSingleModuleFromSingleJarNoDependencies() throws ClassNotFoundException {
+    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
+        .fromSources(MODULE1_PATH)
+        .build();
+    assertThat(moduleService.loadModule(module1Descriptor)).isTrue();
+
+    moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
+        .loadClass("org.apache.geode.Module1");
+  }
+
+  @Test
+  public void loadSingleModuleFromMultipleJarsNoDependencies() throws ClassNotFoundException {
+    ModuleDescriptor moduleDescriptor = new ModuleDescriptor.Builder("multiJarModule", "1.0")
+        .fromSources(MODULE1_PATH, MODULE2_PATH)
+        .build();
+    assertThat(moduleService.loadModule(moduleDescriptor)).isTrue();
+
+    moduleService.getModule(moduleDescriptor.getVersionedName()).getClassLoader()
+        .loadClass("org.apache.geode.Module1");
+    moduleService.getModule(moduleDescriptor.getVersionedName()).getClassLoader()
+        .loadClass("org.apache.geode.Module2");
+  }
+
+  @Test
+  public void loadMultipleModulesFromMultipleJarsNoDependencies() throws ClassNotFoundException {
+    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
+        .fromSources(MODULE1_PATH, MODULE2_PATH)
+        .build();
+    ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module2", "1.0")
+        .fromSources(MODULE3_PATH, MODULE4_PATH)
+        .build();
+
+    assertThat(moduleService.loadModule(module1Descriptor)).isTrue();
+    assertThat(moduleService.loadModule(module2Descriptor)).isTrue();
+
+    moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
+        .loadClass("org.apache.geode.Module1");
+    moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
+        .loadClass("org.apache.geode.Module2");
+
+    moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
+        .loadClass("org.apache.geode.Module3");
+    moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
+        .loadClass("org.apache.geode.Module4");
+  }
+
+  @Test
+  public void modulesCannotAccessOtherModulesMultipleModulesFromMultipleJarsNoDependencies()
+      throws ClassNotFoundException {
+    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
+        .fromSources(MODULE1_PATH, MODULE2_PATH)
+        .build();
+    ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module2", "1.0")
+        .fromSources(MODULE3_PATH, MODULE4_PATH)
+        .build();
+
+    moduleService.loadModule(module1Descriptor);
+    moduleService.loadModule(module2Descriptor);
+
+    assertThatThrownBy(() -> {
+      moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
+          .loadClass("org.apache.geode.Module3");
+    }).isInstanceOf(ClassNotFoundException.class);
+    assertThatThrownBy(() -> {
+      moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
+          .loadClass("org.apache.geode.Module4");
+    }).isInstanceOf(ClassNotFoundException.class);
+
+    assertThatThrownBy(() -> {
+      moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
+          .loadClass("org.apache.geode.Module1");
+    }).isInstanceOf(ClassNotFoundException.class);
+    assertThatThrownBy(() -> {
+      moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
+          .loadClass("org.apache.geode.Module2");
+    }).isInstanceOf(ClassNotFoundException.class);
+  }
+
+  @Test
+  public void loadMultipleModulesFromMultipleJarsWithDependencies() throws ClassNotFoundException {
+    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
+        .fromSources(MODULE1_PATH, MODULE2_PATH)
+        .build();
+    ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module2", "1.0")
+        .fromSources(MODULE3_PATH, MODULE4_PATH)
+        .dependsOnModules(module1Descriptor.getVersionedName())
+        .build();
+
+    assertThat(moduleService.loadModule(module1Descriptor)).isTrue();
+    assertThat(moduleService.loadModule(module2Descriptor)).isTrue();
+
+    moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
+        .loadClass("org.apache.geode.Module1");
+    moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
+        .loadClass("org.apache.geode.Module2");
+    moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
+        .loadClass("org.apache.geode.Module3");
+    moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
+        .loadClass("org.apache.geode.Module4");
+  }
+
+  @Test
+  public void dependenciesDoNotGoBothWaysMultipleModulesFromMultipleJars()
+      throws ClassNotFoundException {
+    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
+        .fromSources(MODULE1_PATH, MODULE2_PATH)
+        .build();
+    ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module2", "1.0")
+        .fromSources(MODULE3_PATH, MODULE4_PATH)
+        .dependsOnModules(module1Descriptor.getVersionedName())
+        .build();
+
+    moduleService.loadModule(module1Descriptor);
+    moduleService.loadModule(module2Descriptor);
+
+    assertThatThrownBy(() -> {
+      moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
+          .loadClass("org.apache.geode.Module3");
+    }).isInstanceOf(ClassNotFoundException.class);
+    assertThatThrownBy(() -> {
+      moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
+          .loadClass("org.apache.geode.Module4");
+    }).isInstanceOf(ClassNotFoundException.class);
+  }
+
+  @Test
+  public void loadMultipleModulesFromSingleJarNoDependencies() throws ClassNotFoundException {
+    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
+        .fromSources(MODULE1_PATH)
+        .build();
+    ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module2", "1.0")
+        .fromSources(MODULE2_PATH)
+        .build();
+    assertThat(moduleService.loadModule(module1Descriptor)).isTrue();
+    assertThat(moduleService.loadModule(module2Descriptor)).isTrue();
+
+    moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
+        .loadClass("org.apache.geode.Module1");
+    moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
+        .loadClass("org.apache.geode.Module2");
+  }
+
+  @Test
+  public void modulesCannotAccessOtherModulesMultipleModulesFromSingleJarNoDependencies()
+      throws ClassNotFoundException {
+    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
+        .fromSources(MODULE1_PATH)
+        .build();
+    ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module2", "1.0")
+        .fromSources(MODULE2_PATH)
+        .build();
+    moduleService.loadModule(module1Descriptor);
+    moduleService.loadModule(module2Descriptor);
+
+    assertThatThrownBy(() -> {
+      moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
+          .loadClass("org.apache.geode.Module2");
+    }).isInstanceOf(ClassNotFoundException.class);
+
+    assertThatThrownBy(() -> {
+      moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
+          .loadClass("org.apache.geode.Module1");
+    }).isInstanceOf(ClassNotFoundException.class);
+  }
+
+  @Test
+  public void loadMultipleModulesFromSingleJarWithDependencies() throws ClassNotFoundException {
+    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
+        .fromSources(MODULE1_PATH)
+        .build();
+    ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module2", "1.0")
+        .fromSources(MODULE2_PATH)
+        .dependsOnModules(module1Descriptor.getVersionedName())
+        .build();
+    assertThat(moduleService.loadModule(module1Descriptor)).isTrue();
+    assertThat(moduleService.loadModule(module2Descriptor)).isTrue();
+
+    moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
+        .loadClass("org.apache.geode.Module1");
+    moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
+        .loadClass("org.apache.geode.Module2");
+    moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
+        .loadClass("org.apache.geode.Module1");
+  }
+
+  @Test
+  public void dependenciesDoNotGoBothWaysMultipleModulesFromSingleJar()
+      throws ClassNotFoundException {
+    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
+        .fromSources(MODULE1_PATH)
+        .build();
+    ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module2", "1.0")
+        .fromSources(MODULE2_PATH)
+        .dependsOnModules(module1Descriptor.getVersionedName())
+        .build();
+    moduleService.loadModule(module1Descriptor);
+    moduleService.loadModule(module2Descriptor);
+
+    assertThatThrownBy(() -> {
+      moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
+          .loadClass("org.apache.geode.Module2");
+    }).isInstanceOf(ClassNotFoundException.class);
+  }
+
+  @Test
+  public void loadModuleMultipleTimes() throws ClassNotFoundException {
+    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
+        .fromSources(MODULE1_PATH)
+        .build();
+    assertThat(moduleService.loadModule(module1Descriptor)).isTrue();
+    assertThat(moduleService.loadModule(module1Descriptor)).isFalse();
+
+    moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
+        .loadClass("org.apache.geode.Module1");
+  }
+
+  @Test
+  public void loadModulesWithSameNameAndDifferentVersions() throws ClassNotFoundException {
+    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
+        .fromSources(MODULE1_PATH)
+        .build();
+    moduleService.loadModule(module1Descriptor);
+    ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module1", "2.0")
+        .fromSources(MODULE2_PATH)
+        .build();
+    moduleService.loadModule(module2Descriptor);
+
+    moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
+        .loadClass("org.apache.geode.Module1");
+    assertThatThrownBy(() -> {
+      moduleService.getModule(module1Descriptor.getVersionedName()).getClassLoader()
+          .loadClass("org.apache.geode.Module2");
+    }).isInstanceOf(ClassNotFoundException.class);
+
+    moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
+        .loadClass("org.apache.geode.Module2");
+    assertThatThrownBy(() -> {
+      moduleService.getModule(module2Descriptor.getVersionedName()).getClassLoader()
+          .loadClass("org.apache.geode.Module1");
+    }).isInstanceOf(ClassNotFoundException.class);
+  }
+
+  @Test
+  public void loadModuleFromInvalidSource() {
+    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
+        .fromSources("/there/is/nothing/here.jar")
+        .build();
+    assertThat(moduleService.loadModule(module1Descriptor)).isFalse();
+    assertThat(moduleService.getModule(module1Descriptor.getVersionedName())).isNull();
+  }
+
+  @Test
+  public void loadModuleFromMixOfValidAndInvalidSources() {
+    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
+        .fromSources("/there/is/nothing/here.jar", MODULE1_PATH)
+        .build();
+    assertThat(moduleService.loadModule(module1Descriptor)).isFalse();
+    assertThat(moduleService.getModule(module1Descriptor.getVersionedName())).isNull();
+  }
+
+  @Test
+  public void loadModuleWithInvalidDependencies() {
+    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
+        .fromSources(MODULE1_PATH)
+        .dependsOnModules("this_is_invalid")
+        .build();
+    assertThat(moduleService.loadModule(module1Descriptor)).isFalse();
+    assertThat(moduleService.getModule(module1Descriptor.getVersionedName())).isNull();
+  }
+
+  @Test
+  public void loadModuleWithMixOfValidAndInvalidDependencies() {
+    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
+        .fromSources(MODULE1_PATH)
+        .build();
+    ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module2", "1.0")
+        .fromSources(MODULE2_PATH)
+        .dependsOnModules("this_is_invalid", module1Descriptor.getVersionedName())
+        .build();
+    moduleService.loadModule(module1Descriptor);
+    assertThat(moduleService.loadModule(module2Descriptor)).isFalse();
+    assertThat(moduleService.getModule(module2Descriptor.getVersionedName())).isNull();
+  }
+
+  @Test
+  public void getModuleNoModulesLoaded() {
+    assertThat(moduleService.getModule("module1:1.0")).isNull();
+  }
+
+  @Test
+  public void getModuleWithSingeModuleLoaded() {
+    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
+        .fromSources(MODULE1_PATH)
+        .build();
+    moduleService.loadModule(module1Descriptor);
+    Module module = moduleService.getModule(module1Descriptor.getVersionedName());
+    assertThat(module).isNotNull();
+    assertThat(module.getName()).isEqualTo(module1Descriptor.getVersionedName());
+  }
+
+  @Test
+  public void getModuleWithMultipleModulesLoaded() {
+    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);
+
+    Module module1 = moduleService.getModule(module1Descriptor.getVersionedName());
+    assertThat(module1).isNotNull();
+    assertThat(module1.getName()).isEqualTo(module1Descriptor.getVersionedName());
+
+    Module module2 = moduleService.getModule(module2Descriptor.getVersionedName());
+    assertThat(module2).isNotNull();
+    assertThat(module2.getName()).isEqualTo(module2Descriptor.getVersionedName());
+  }
+}
diff --git a/geode-modules/src/test/resources/expected-pom.xml b/geode-modules/src/test/resources/expected-pom.xml
new file mode 100644
index 0000000..50c2beb
--- /dev/null
+++ b/geode-modules/src/test/resources/expected-pom.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <!--
+  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.
+  -->
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.geode</groupId>
+  <artifactId>geode-modules</artifactId>
+  <version>1.13.0-SNAPSHOT</version>
+  <name>Apache Geode</name>
+  <description>Apache Geode provides a database-like consistency model, reliable transaction processing and a shared-nothing architecture to maintain very low latency performance with high concurrency processing</description>
+  <url>http://geode.apache.org</url>
+  <licenses>
+    <license>
+      <name>The Apache Software License, Version 2.0</name>
+      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+    </license>
+  </licenses>
+  <scm>
+    <connection>scm:git:https://github.com:apache/geode.git</connection>
+    <developerConnection>scm:git:https://github.com:apache/geode.git</developerConnection>
+    <url>https://github.com/apache/geode</url>
+  </scm>
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
+        <artifactId>geode-all-bom</artifactId>
+        <version>1.13.0-SNAPSHOT</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.geode</groupId>
+      <artifactId>geode-common</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.geode</groupId>
+      <artifactId>geode-common-services</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.modules</groupId>
+      <artifactId>jboss-modules</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.geode</groupId>
+      <artifactId>geode-logging</artifactId>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.geode</groupId>
+      <artifactId>geode-log4j</artifactId>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-core</artifactId>
+      <scope>runtime</scope>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/geode-modules/src/testModules/module1/java/org/apache/geode/Module1.java b/geode-modules/src/testModules/module1/java/org/apache/geode/Module1.java
new file mode 100644
index 0000000..684a71c
--- /dev/null
+++ b/geode-modules/src/testModules/module1/java/org/apache/geode/Module1.java
@@ -0,0 +1,19 @@
+/*
+ * 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.geode;
+
+public class Module1 {
+}
diff --git a/geode-modules/src/testModules/module2/java/org.apache.geode/Module2.java b/geode-modules/src/testModules/module2/java/org.apache.geode/Module2.java
new file mode 100644
index 0000000..9cbac0f
--- /dev/null
+++ b/geode-modules/src/testModules/module2/java/org.apache.geode/Module2.java
@@ -0,0 +1,19 @@
+/*
+ * 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.geode;
+
+public class Module2 {
+}
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
new file mode 100644
index 0000000..87035eb
--- /dev/null
+++ b/geode-modules/src/testModules/module3/java/org/apache/geode/Module3.java
@@ -0,0 +1,19 @@
+/*
+ * 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.geode;
+
+public class Module3 {
+}
diff --git a/geode-modules/src/testModules/module4/java/org/apache/geode/Module4.java b/geode-modules/src/testModules/module4/java/org/apache/geode/Module4.java
new file mode 100644
index 0000000..c494905
--- /dev/null
+++ b/geode-modules/src/testModules/module4/java/org/apache/geode/Module4.java
@@ -0,0 +1,19 @@
+/*
+ * 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.geode;
+
+public class Module4 {
+}
diff --git a/settings.gradle b/settings.gradle
index 501a179..cefea67 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -68,6 +68,8 @@ include 'geode-concurrency-test'
 include 'boms:geode-client-bom'
 include 'boms:geode-all-bom'
 include 'static-analysis:pmd-rules'
+include 'geode-common-services'
+include 'geode-modules'
 
 
 ['1.0.0-incubating',


[geode] 01/08: GEODE-8037 - Create BootstrappingService interface. (#5046)

Posted by ud...@apache.org.
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 82e14054c2af08846c22f3a8857000c89dd4a522
Author: Patrick Johnson <pj...@pivotal.io>
AuthorDate: Wed May 6 10:36:31 2020 -0700

    GEODE-8037 - Create BootstrappingService interface. (#5046)
---
 .../bootstrapping/BootstrappingService.java        | 44 ++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/geode-common-services/src/main/java/org/apache/geode/services/bootstrapping/BootstrappingService.java b/geode-common-services/src/main/java/org/apache/geode/services/bootstrapping/BootstrappingService.java
new file mode 100644
index 0000000..d23acc7
--- /dev/null
+++ b/geode-common-services/src/main/java/org/apache/geode/services/bootstrapping/BootstrappingService.java
@@ -0,0 +1,44 @@
+/*
+ * 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.geode.services.bootstrapping;
+
+import java.util.Properties;
+
+import org.apache.geode.annotations.Experimental;
+
+/**
+ * Service responsible for bootstrapping the environment and Geode components.
+ *
+ * @since Geode 1.13.0
+ */
+@Experimental
+public interface BootstrappingService {
+
+  /**
+   * Start and initialize Geode.
+   *
+   * @param properties system properties to use when bootstrapping the environment.
+   * @throws Exception - thrown if unable to bootstrap system.
+   */
+  void init(Properties properties) throws Exception;
+
+  /**
+   * Shuts down the environment and previously bootstrapped Geode components.
+   *
+   * @throws Exception - thrown if unable to shutdown.
+   */
+  void shutdown() throws Exception;
+}


[geode] 08/08: GEODE-8239 - Add gradle config to add 'Class-Path' and 'Dependent-Modules' attirbutes to manifest file. (#5297)

Posted by ud...@apache.org.
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 23babb80c770e50c0e5f8b841e51fc20e6a27dbc
Author: Patrick Johnson <pj...@pivotal.io>
AuthorDate: Wed Jun 24 13:12:39 2020 -0700

    GEODE-8239 - Add gradle config to add 'Class-Path' and 'Dependent-Modules' attirbutes to manifest file. (#5297)
    
    GEODE-8043 - Create JBossModuleService and implement loadModule. (#5081)
    
    GEODE-8294 - Integrate ModuleService into Geode.
    	Integrated ModuleService into geode-membership.
    	Integrate ModuleService into geode-cq.
    	Integrate ModuleService into WAnServiceProvider
    	Integrate ModuleService into ServerConnectionfactory.
    	Integrate ModuleService into ListCollectingServiceLoader and InternalDistributedSystemMetricsService.
    	Integrate ModuleService into HandshakeRequestOperationHandler and ValueSerializer
    	Integrate ModuleService into CacheXml.
            Integrate ModuleService into CommandManager.
            Cleaned up library dependencies
            Moved BootstrappingService.java to geode-common-services
            Integrate ModuleService into tests and comments..
    
    GEODE-8306 - Introduce GeodeEntityResolver2Interface.
---
 .../src/test/resources/expected-pom.xml            |   36 +
 .../gradle/plugins/DependencyConstraints.groovy    |   11 +-
 extensions/geode-modules-session/build.gradle      |    2 +
 extensions/geode-modules-test/build.gradle         |    2 +
 extensions/geode-modules-tomcat7/build.gradle      |    4 +
 extensions/geode-modules-tomcat8/build.gradle      |    4 +
 extensions/geode-modules-tomcat9/build.gradle      |    1 +
 extensions/geode-modules/build.gradle              |    2 +
 geode-assembly/build.gradle                        | 1075 ++++----
 .../commands/StartServerCommandAcceptanceTest.java |    5 +-
 .../integrationTest/resources/assembly_content.txt |   12 +
 .../resources/dependency_classpath.txt             |    3 +
 geode-book/.gitignore                              |    2 -
 geode-book/Gemfile                                 |   22 -
 geode-book/Gemfile.lock                            |  207 --
 geode-book/README.md                               |  115 -
 geode-book/config.yml                              |   48 -
 .../source/archive_menus/_default.erb              |   28 -
 .../source/images/Apache_Geode_logo_symbol.png     |  Bin 13871 -> 0 bytes
 .../images/Apache_Geode_logo_symbol_white.png      |  Bin 21485 -> 0 bytes
 .../master_middleman/source/images/favicon.ico     |  Bin 1317 -> 0 bytes
 .../master_middleman/source/javascripts/book.js    |   31 -
 .../source/javascripts/waypoints/context.js        |  315 ---
 .../source/javascripts/waypoints/group.js          |  120 -
 .../javascripts/waypoints/noframeworkAdapter.js    |  228 --
 .../source/javascripts/waypoints/sticky.js         |   78 -
 .../source/javascripts/waypoints/waypoint.js       |  175 --
 .../source/layouts/_book-footer.erb                |   23 -
 .../source/layouts/_local-header.erb               |   27 -
 .../master_middleman/source/layouts/_title.erb     |   21 -
 .../source/stylesheets/book-styles.scss            |   18 -
 .../stylesheets/partials/_book-base-values.scss    |   14 -
 .../source/stylesheets/partials/_book-vars.scss    |   33 -
 .../source/subnavs/geode-subnav.erb                | 2518 ------------------
 geode-book/redirects.rb                            |   18 -
 geode-common-services/build.gradle                 |   40 +-
 .../bootstrapping/BootstrappingService.java        |    7 +-
 .../services/management/ManagementService.java     |    8 +-
 .../geode/services/module/ModuleDescriptor.java    |   19 +-
 .../geode/services/module/ModuleService.java       |   13 +-
 .../module/impl/ServiceLoaderModuleService.java    |  116 +
 .../apache/geode/services/result/impl/Failure.java |    0
 .../apache/geode/services/result/impl/Success.java |    0
 .../src/test/resources/expected-pom.xml            |   10 +-
 geode-common/build.gradle                          |   37 -
 geode-connectors/build.gradle                      |    5 +
 .../jdbc/internal/TestConfigService.java           |    4 +-
 .../cli/DestroyDataSourceCommandDUnitTest.java     |   10 +-
 ...apache.geode.management.cli.GeodeCommandMarker} |    0
 .../jdbc/internal/JdbcConnectorServiceTest.java    |    4 +-
 .../cli/ConnectionsCommandManagerTest.java         |   30 +-
 geode-core/build.gradle                            |   16 +-
 .../apache/geode/cache30/CacheXml66DUnitTest.java  |  262 +-
 .../apache/geode/cache30/CacheXml70DUnitTest.java  |   12 +-
 .../apache/geode/cache30/CacheXml80DUnitTest.java  |   13 +-
 .../apache/geode/cache30/CacheXml81DUnitTest.java  |   11 +-
 .../geode/cache30/CacheXmlGeode10DUnitTest.java    |   18 +-
 ...ReconnectWithClusterConfigurationDUnitTest.java |    5 +-
 .../ClusterDistributionManagerDUnitTest.java       |    5 +-
 .../mock/AlterMockCacheExtensionFunction.java      |   10 +-
 .../mock/AlterMockRegionExtensionFunction.java     |   10 +-
 .../mock/CreateMockCacheExtensionFunction.java     |   10 +-
 .../mock/CreateMockRegionExtensionFunction.java    |   10 +-
 .../mock/DestroyMockCacheExtensionFunction.java    |   10 +-
 .../mock/DestroyMockRegionExtensionFunction.java   |   11 +-
 .../extension/mock/MockExtensionCommands.java      |   23 +-
 ...PersistentPartitionedRegionDistributedTest.java |   14 +-
 .../cache/partitioned/ShutdownAllDUnitTest.java    |    6 +-
 ...apache.geode.management.cli.GeodeCommandMarker} |    0
 .../AutoConnectionSourceImplJUnitTest.java         |   15 +-
 .../cache/execute/CoreFunctionSecurityTest.java    |   16 +-
 .../ServerLauncherIntegrationTestCase.java         |   11 +-
 ...utedSystemBuilderForTestingIntegrationTest.java |   11 +-
 ...nalDistributedSystemBuilderIntegrationTest.java |   17 +-
 .../InternalDistributedSystemJUnitTest.java        |   25 +-
 ...DistributedSystemLockMemoryIntegrationTest.java |   19 +-
 ...alDistributedSystemSecurityIntegrationTest.java |    9 +-
 .../internal/InternalLocatorIntegrationTest.java   |   23 +-
 .../internal/membership/MembershipJUnitTest.java   |   11 +-
 .../cache/ServerBuilderIntegrationTest.java        |   26 +-
 .../tier/sockets/AcceptorImplIntegrationTest.java  |    5 +-
 .../xmlcache/CacheXmlGeneratorIntegrationTest.java |    5 +-
 .../cache/xmlcache/CacheXmlParserJUnitTest.java    |    9 +-
 .../internal/EntityInfoIntegrationTest.java        |    5 +-
 ...StartupConfigurationLoggingIntegrationTest.java |    3 +-
 .../api/LoggingWithLocatorIntegrationTest.java     |    7 +-
 .../utils/XmlUtilsAddNewNodeJUnitTest.java         |   97 +-
 .../geode/admin/AdminDistributedSystemFactory.java |    6 +-
 .../admin/internal/AdminDistributedSystemImpl.java |    6 +-
 .../org/apache/geode/admin/jmx/AgentFactory.java   |    6 +-
 .../internal/AdminDistributedSystemJmxImpl.java    |    3 +-
 .../apache/geode/admin/jmx/internal/AgentImpl.java |   10 +-
 .../geode/admin/jmx/internal/AgentLauncher.java    |   11 +-
 .../java/org/apache/geode/cache/CacheFactory.java  |   14 +-
 .../geode/cache/client/ClientCacheFactory.java     |   14 +-
 .../internal/QueryConfigurationServiceImpl.java    |    3 +-
 .../cache/query/internal/cq/CqServiceProvider.java |   45 +-
 .../geode/distributed/DistributedSystem.java       |    5 +-
 .../java/org/apache/geode/distributed/Locator.java |   87 +-
 .../apache/geode/distributed/LocatorLauncher.java  |    3 +-
 .../internal/ClusterDistributionManager.java       |   15 +-
 .../distributed/internal/DistributionImpl.java     |   10 +-
 .../InternalConfigurationPersistenceService.java   |   27 +-
 .../internal/InternalDistributedSystem.java        |   68 +-
 .../distributed/internal/InternalLocator.java      |  381 ++-
 .../apache/geode/internal/DistributionLocator.java |    4 +-
 .../apache/geode/internal/cache/CacheConfig.java   |    1 -
 .../geode/internal/cache/CacheFactoryStatics.java  |    6 +-
 .../geode/internal/cache/CacheServerImpl.java      |  261 +-
 .../apache/geode/internal/cache/CacheService.java  |    5 +-
 .../geode/internal/cache/GemFireCacheImpl.java     | 2675 ++++++++++----------
 .../geode/internal/cache/InternalCacheBuilder.java |   43 +-
 .../apache/geode/internal/cache/ServerBuilder.java |    8 +-
 .../client/protocol/ClientProtocolService.java     |    3 +
 .../protocol/ClientProtocolServiceLoader.java      |   18 +-
 .../tier/sockets/ServerConnectionFactory.java      |    5 +-
 .../internal/cache/wan/WANServiceProvider.java     |   43 +-
 .../internal/cache/xmlcache/CacheCreation.java     |   14 +-
 .../geode/internal/cache/xmlcache/CacheXml.java    |   53 +-
 .../internal/cache/xmlcache/CacheXmlGenerator.java |    6 +-
 .../internal/cache/xmlcache/CacheXmlParser.java    |   36 +-
 .../cache/xmlcache/ClientCacheCreation.java        |    4 +-
 .../cache/xmlcache/DefaultEntityResolver2.java     |   31 +-
 .../cache/xmlcache/GeodeEntityResolver.java        |   17 +-
 .../cache/xmlcache/GeodeEntityResolver2.java       |   36 +
 .../cache/xmlcache/PivotalEntityResolver.java      |   16 +-
 .../geode/internal/cache/xmlcache/XmlParser.java   |    5 +-
 .../org/apache/geode/internal/logging/Banner.java  |    5 +-
 .../internal/util/CollectingServiceLoader.java     |    5 +-
 .../internal/util/ListCollectingServiceLoader.java |   57 +-
 .../geode/logging/internal/Configuration.java      |   26 +-
 .../geode/logging/internal/ConfigurationInfo.java  |    5 +-
 .../logging/internal/LoggingProviderLoader.java    |   13 +-
 .../geode/logging/internal/LoggingSession.java     |    5 +-
 .../configuration/domain/CacheElement.java         |   18 +-
 .../configuration/domain/Configuration.java        |    5 +-
 .../internal/configuration/domain/XmlEntity.java   |   36 +-
 .../messages/ConfigurationResponse.java            |    5 +-
 .../internal/configuration/utils/XmlUtils.java     |   46 +-
 .../InternalDistributedSystemMetricsService.java   |   66 +-
 .../geode/metrics/internal/MetricsService.java     |    3 +-
 ...e.internal.cache.xmlcache.GeodeEntityResolver2} |    0
 .../QueryConfigurationServiceImplTest.java         |   31 +-
 ...igurationPersistenceServiceDeployedJarTest.java |    5 +-
 ...nternalConfigurationPersistenceServiceTest.java |   49 +-
 ...rnalDistributedSystemStatisticsManagerTest.java |   21 +-
 .../distributed/internal/InternalLocatorTest.java  |    8 +-
 .../geode/internal/cache/CacheServerImplTest.java  |   26 +-
 .../internal/cache/GemFireCacheImplCloseTest.java  |    6 +-
 .../geode/internal/cache/GemFireCacheImplTest.java |   19 +-
 ...ernalCacheBuilderAllowsMultipleSystemsTest.java |   65 +-
 .../internal/cache/InternalCacheBuilderTest.java   |  107 +-
 .../geode/internal/cache/ServerBuilderTest.java    |   38 +-
 .../tier/sockets/ServerConnectionFactoryTest.java  |   44 +-
 .../cache/tier/sockets/ServerConnectionTest.java   |   12 +-
 .../cache/xmlcache/AbstractEntityResolverTest.java |   23 +-
 .../internal/cache/xmlcache/CacheCreationTest.java |   50 +-
 .../cache/xmlcache/DefaultEntityResolver2Test.java |   11 +-
 .../xmlcache/GeodeEntityResolverJUnitTest.java     |    7 +-
 .../cache/xmlcache/GeodeEntityResolverTest.java    |   26 +-
 .../xmlcache/PivotalEntityResolverJUnitTest.java   |    5 +-
 .../cache/xmlcache/PivotalEntityResolverTest.java  |   19 +-
 .../cache/xmlcache/RegionCreationJUnitTest.java    |    5 +-
 .../apache/geode/internal/logging/BannerTest.java  |    4 +-
 .../internal/util/ArgumentRedactorJUnitTest.java   |    6 +-
 .../util/InternalCacheBuilderTestUtil.java         |    9 +-
 .../util/ListCollectingServiceLoaderTest.java      |   49 +-
 .../internal/LoggingProviderLoaderTest.java        |    8 +-
 .../geode/logging/internal/LoggingSessionTest.java |    7 +-
 .../api/LocatorClusterManagementServiceTest.java   |    5 +-
 .../domain/CacheElementJUnitTest.java              |   15 +-
 .../configuration/domain/ConfigurationTest.java    |    8 +-
 .../configuration/utils/XmlUtilsJUnitTest.java     |   75 +-
 ...DistributedSystemMetricsServiceBuilderTest.java |   45 +-
 geode-cq/build.gradle                              |    6 +-
 .../build.gradle                                   |   16 +-
 .../org/apache/geode/graphing/Dependencies.java    |  139 +
 .../src/test/resources/expected-pom.xml            |   10 +-
 geode-dunit/build.gradle                           |    1 +
 .../management/internal/cli/HeadlessGfsh.java      |   15 +-
 .../dunit/cache/internal/JUnit4CacheTestCase.java  |   13 +-
 .../geode/test/dunit/rules/CacheXmlRule.java       |   10 +-
 .../geode/test/junit/rules/GfshCommandRule.java    |    8 +-
 geode-experimental-driver/build.gradle             |    1 +
 geode-gfsh/build.gradle                            |    8 +-
 .../cli/commands/AlterCompressorDUnitTest.java     |    6 +-
 .../CreateJndiBindingCommandDUnitTest.java         |    5 +-
 .../commands/CreatePooledJndiBindingDUnitTest.java |    6 +-
 .../DestroyJndiBindingCommandDUnitTest.java        |    6 +-
 .../DestroySecondJndiBindingCommandDUnitTest.java  |    6 +-
 .../internal/cli/HeadlessGfshIntegrationTest.java  |    5 +-
 .../internal/cli/shell/GfshHistoryJUnitTest.java   |    9 +-
 .../cli/shell/GfshInitFileIntegrationTest.java     |   26 +-
 .../geode/management/cli/CommandService.java       |    5 +-
 .../geode/management/cli/GeodeCommandMarker.java   |   25 +
 .../apache/geode/management/cli/GfshCommand.java   |   13 +-
 .../management/internal/cli/CommandManager.java    |   74 +-
 .../geode/management/internal/cli/GfshParser.java  |    4 +-
 .../geode/management/internal/cli/Launcher.java    |   20 +-
 .../cli/commands/AlterRuntimeConfigCommand.java    |    2 +-
 .../internal/cli/commands/CreateRegionCommand.java |    5 +-
 .../commands/DestroyAsyncEventQueueCommand.java    |    3 +-
 .../cli/commands/DestroyDiskStoreCommand.java      |    3 +-
 .../cli/commands/DestroyGatewaySenderCommand.java  |    3 +-
 .../cli/commands/DestroyRegionCommand.java         |    3 +-
 .../ImportClusterConfigurationCommand.java         |    2 +-
 .../internal/cli/commands/OfflineGfshCommand.java  |   17 +-
 .../functions/DestroyAsyncEventQueueFunction.java  |   13 +-
 .../cli/functions/DestroyDiskStoreFunction.java    |   10 +-
 .../functions/FetchRegionAttributesFunction.java   |   12 +-
 .../functions/GatewaySenderDestroyFunction.java    |   13 +-
 .../cli/functions/RegionCreateFunction.java        |   14 +-
 .../cli/functions/RegionDestroyFunction.java       |   14 +-
 .../internal/cli/remote/MemberCommandService.java  |   13 +-
 .../cli/remote/OnlineCommandProcessor.java         |   11 +-
 .../geode/management/internal/cli/shell/Gfsh.java  |   17 +-
 .../sanctioned-geode-gfsh-serializables.txt        |   12 +-
 .../internal/cli/CommandManagerJUnitTest.java      |   67 +-
 .../commands/AlterAsyncEventQueueCommandTest.java  |    5 +-
 .../commands/CommandAvailabilityIndicatorTest.java |    6 +-
 .../DestroyAsyncEventQueueFunctionTest.java        |    8 +-
 .../GatewaySenderDestroyFunctionTest.java          |    5 +-
 .../functions/RegionCreateFunctionJUnitTest.java   |    5 +-
 .../cli/functions/RegionDestroyFunctionTest.java   |    5 +-
 .../internal/cli/help/HelperUnitTest.java          |    4 +-
 .../internal/cli/remote/CommandExecutorTest.java   |    5 +-
 .../cli/remote/MemberCommandServiceTest.java       |   50 +-
 .../cli/remote/OnlineCommandProcessorTest.java     |   10 +-
 .../cli/shell/GfshConsoleModeUnitTest.java         |    7 +-
 .../cli/shell/GfshExecutionStrategyTest.java       |   10 +-
 .../cli/shell/GfshHeadlessModeUnitTest.java        |    7 +-
 ...apache.geode.management.cli.GeodeCommandMarker} |    0
 geode-http-service/build.gradle                    |   10 +-
 .../geode/internal/cache/InternalHttpService.java  |    3 +-
 .../internal/InternalHttpServiceJunitTest.java     |    6 +-
 .../src/test/resources/expected-pom.xml            |    5 -
 geode-junit/build.gradle                           |    1 +
 .../AnalyzeSerializablesJUnitTestBase.java         |   15 +-
 .../CommandAvailabilityIndicatorTestHelper.java    |    6 +-
 .../geode/test/junit/rules/GfshParserRule.java     |    4 +-
 geode-log4j/build.gradle                           |    2 +
 .../impl/ConfigurationIntegrationTest.java         |   18 +-
 ...gurationWithLogLevelChangesIntegrationTest.java |    4 +-
 .../internal/impl/FastLoggerIntegrationTest.java   |    4 +-
 ...FastLoggerWithDefaultConfigIntegrationTest.java |    4 +-
 .../internal/impl/LoggingProviderLoaderTest.java   |    5 +-
 geode-logging/build.gradle                         |    2 +-
 geode-logging/src/test/resources/expected-pom.xml  |   13 +-
 geode-lucene/build.gradle                          |    5 +
 .../internal/LuceneServiceImplIntegrationTest.java |    6 +-
 .../LuceneIndexXmlParserIntegrationJUnitTest.java  |    6 +-
 .../lucene/test/LuceneFunctionSecurityTest.java    |    5 +-
 .../cache/lucene/internal/LuceneServiceImpl.java   |    4 +-
 .../internal/cli/LuceneCreateIndexCommand.java     |    6 +-
 .../cli/functions/LuceneCreateIndexFunction.java   |   13 +-
 ...apache.geode.management.cli.GeodeCommandMarker} |    0
 .../sanctioned-geode-lucene-serializables.txt      |    4 +-
 .../LuceneCreateIndexFunctionJUnitTest.java        |   11 +-
 geode-management/build.gradle                      |    1 +
 geode-membership/build.gradle                      |   14 +
 .../MembershipDependenciesJUnitTest.java           |    2 +
 .../membership/api/MembershipAPIArchUnitTest.java  |    1 +
 .../membership/gms/GMSMembershipJUnitTest.java     |    4 +-
 .../membership/gms/MembershipIntegrationTest.java  |    5 +-
 .../gms/fd/GMSHealthMonitorJUnitTest.java          |    4 +-
 .../locator/GMSLocatorRecoveryIntegrationTest.java |    6 +-
 .../gms/membership/GMSJoinLeaveJUnitTest.java      |    6 +-
 .../gms/messenger/JGroupsMessengerJUnitTest.java   |    6 +-
 .../gms/messenger/StatRecorderJUnitTest.java       |    6 +-
 .../internal/membership/api/MembershipBuilder.java |    5 +-
 .../internal/membership/gms/GMSMembership.java     |    4 +-
 .../membership/gms/MembershipBuilderImpl.java      |    9 +-
 .../internal/membership/gms/Services.java          |   11 +-
 .../membership/gms/fd/GMSHealthMonitor.java        |   18 +-
 .../membership/gms/interfaces/Service.java         |    3 +-
 .../membership/gms/membership/GMSJoinLeave.java    |  220 +-
 .../membership/gms/messenger/JGroupsMessenger.java |  296 +--
 geode-memcached/build.gradle                       |    1 +
 .../internal/memcached/GeodeMemcachedService.java  |    3 +-
 .../build.gradle                                   |   22 +-
 .../impl/BootstrappingServiceImpl.java             |  126 +
 ...ode.services.bootstrapping.BootstrappingService |    1 +
 .../src/test/resources/expected-pom.xml            |   14 +-
 .../build.gradle                                   |   24 +-
 .../management/impl/ManagementServiceImpl.java     |   61 +
 ...che.geode.services.management.ManagementService |    1 +
 .../src/test/resources/expected-pom.xml            |    9 +-
 .../build.gradle                                   |   18 +-
 .../geode/services/module/impl/PrototypeTest.java  |   97 +
 .../geode/services/module/impl/PrototypeTest2.java |   97 +
 .../src/test/resources/expected-pom.xml            |    8 +-
 geode-modules/build.gradle                         |   61 +-
 .../services/module/impl/GeodeModuleLoader.java    |   53 +
 .../module/impl/JBossModuleServiceImpl.java        |  111 +-
 .../internal/finder/DelegatingModuleFinder.java    |   18 +-
 .../module/internal/loader/GeodeModuleLoader.java  |   30 +-
 .../main/java/org/jboss/modules/GeodeJDKPaths.java |  163 ++
 ...JarModuleFinder.java => GeodeModuleFinder.java} |  136 +-
 ...erviceImplWithoutPopulatedManifestFileTest.java |  117 +-
 ...esServiceImplWithPopulatedManifestFileTest.java |   36 +-
 .../jboss/modules/GeodeJarModuleFinderTest.java    |   48 +-
 geode-modules/src/test/resources/expected-pom.xml  |   28 +-
 .../module1/java/org/apache/geode/Module1.java     |   19 +-
 .../module2/java/org.apache.geode/Module2.java     |   19 +-
 .../module3/java/org/apache/geode/Module3.java     |   19 +-
 .../module4/java/org/apache/geode/Module4.java     |   19 +-
 geode-old-client-support/build.gradle              |    6 +
 .../gemstone/gemfire/OldClientSupportProvider.java |    3 +-
 geode-protobuf/build.gradle                        |    9 +-
 .../protobuf/v1/ProtobufProtocolService.java       |    8 +-
 .../protobuf/v1/ProtobufStreamProcessor.java       |    6 +-
 .../security/HandshakeRequestOperationHandler.java |   25 +-
 .../registry/ProtobufOperationContextRegistry.java |   10 +-
 .../protocol/serialization/ValueSerializer.java    |    4 +-
 .../protobuf/ProtobufStreamProcessorTest.java      |    5 +-
 .../v1/ProtobufProtocolServiceJUnitTest.java       |    3 +
 geode-rebalancer/build.gradle                      |    2 +
 geode-redis/build.gradle                           |    7 +
 .../geode/redis/internal/GeodeRedisService.java    |    3 +-
 ...apache.geode.management.cli.GeodeCommandMarker} |    0
 geode-wan/build.gradle                             |   11 +-
 .../geode/cache/CacheXml70GatewayDUnitTest.java    |   10 +-
 .../geode/cache/CacheXml80GatewayDUnitTest.java    |    8 +-
 .../geode/internal/cache/wan/WANTestBase.java      |    5 +-
 ...hutdownAllPersistentGatewaySenderDUnitTest.java |    4 +-
 ...ewayReceiverXmlParsingValidationsJUnitTest.java |   20 +-
 ...ipleReceiversDefinedInClusterConfiguration.java |   12 +-
 geode-web-management/build.gradle                  |    1 +
 geode-web/build.gradle                             |    1 +
 gradle.properties                                  |    1 +
 settings.gradle                                    |   10 +-
 331 files changed, 6185 insertions(+), 8297 deletions(-)

diff --git a/boms/geode-all-bom/src/test/resources/expected-pom.xml b/boms/geode-all-bom/src/test/resources/expected-pom.xml
index 02cc94e..0d4d702 100644
--- a/boms/geode-all-bom/src/test/resources/expected-pom.xml
+++ b/boms/geode-all-bom/src/test/resources/expected-pom.xml
@@ -554,6 +554,12 @@
         <scope>compile</scope>
       </dependency>
       <dependency>
+        <groupId>org.graphstream</groupId>
+        <artifactId>gs-core</artifactId>
+        <version>1.3</version>
+        <scope>compile</scope>
+      </dependency>
+      <dependency>
         <groupId>com.fasterxml.jackson.core</groupId>
         <artifactId>jackson-annotations</artifactId>
         <version>2.10.1</version>
@@ -927,6 +933,12 @@
       </dependency>
       <dependency>
         <groupId>org.apache.geode</groupId>
+        <artifactId>geode-dep-graph</artifactId>
+        <version>${version}</version>
+        <scope>compile</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
         <artifactId>geode-dunit</artifactId>
         <version>${version}</version>
         <scope>compile</scope>
@@ -957,6 +969,12 @@
       </dependency>
       <dependency>
         <groupId>org.apache.geode</groupId>
+        <artifactId>geode-launcher</artifactId>
+        <version>${version}</version>
+        <scope>compile</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
         <artifactId>geode-log4j</artifactId>
         <version>${version}</version>
         <scope>compile</scope>
@@ -993,12 +1011,30 @@
       </dependency>
       <dependency>
         <groupId>org.apache.geode</groupId>
+        <artifactId>geode-module-bootstrapping</artifactId>
+        <version>${version}</version>
+        <scope>compile</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
+        <artifactId>geode-module-management</artifactId>
+        <version>${version}</version>
+        <scope>compile</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
         <artifactId>geode-modules</artifactId>
         <version>${version}</version>
         <scope>compile</scope>
       </dependency>
       <dependency>
         <groupId>org.apache.geode</groupId>
+        <artifactId>geode-modules-proto</artifactId>
+        <version>${version}</version>
+        <scope>compile</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
         <artifactId>geode-old-client-support</artifactId>
         <version>${version}</version>
         <scope>compile</scope>
diff --git a/buildSrc/src/main/groovy/org/apache/geode/gradle/plugins/DependencyConstraints.groovy b/buildSrc/src/main/groovy/org/apache/geode/gradle/plugins/DependencyConstraints.groovy
index ce8c4b1..960af4e 100644
--- a/buildSrc/src/main/groovy/org/apache/geode/gradle/plugins/DependencyConstraints.groovy
+++ b/buildSrc/src/main/groovy/org/apache/geode/gradle/plugins/DependencyConstraints.groovy
@@ -21,14 +21,14 @@ import org.gradle.api.Project
 class DependencyConstraints implements Plugin<Project> {
   /** By necessity, the version of those plugins used in the build-scripts are defined in the
    * buildscript {} configuration in the root project's build.gradle. */
-  static Map<String,String> disparateDependencies = initExternalDependencies()
+  static Map<String, String> disparateDependencies = initExternalDependencies()
 
   static String get(String name) {
     return disparateDependencies.get(name)
   }
 
   static private Map<String, String> initExternalDependencies() {
-    Map<String,String> deps = new HashMap<>()
+    Map<String, String> deps = new HashMap<>()
     // These versions are consumed beyond the scope of source set dependencies.
 
     deps.put("jboss-modules.version", "1.10.1.Final")
@@ -77,7 +77,7 @@ class DependencyConstraints implements Plugin<Project> {
   void apply(Project project) {
     def dependencySet = { Map<String, String> group_and_version, Closure closure ->
       DependencySetHandler delegate =
-          new DependencySetHandler(group_and_version.get("group"), group_and_version.get("version"), project)
+              new DependencySetHandler(group_and_version.get("group"), group_and_version.get("version"), project)
       closure.setDelegate(delegate)
       closure.call(delegate)
     }
@@ -100,12 +100,12 @@ class DependencyConstraints implements Plugin<Project> {
         api(group: 'com.google.protobuf', name: 'protobuf-java', version: get('protobuf-java.version'))
         api(group: 'com.healthmarketscience.rmiio', name: 'rmiio', version: '2.1.2')
         api(group: 'com.mockrunner', name: 'mockrunner-servlet', version: '2.0.4')
-        api(group: 'com.nimbusds', name:'nimbus-jose-jwt', version:'8.11')
+        api(group: 'com.nimbusds', name: 'nimbus-jose-jwt', version: '8.11')
         api(group: 'com.sun.activation', name: 'javax.activation', version: '1.2.0')
         api(group: 'com.sun.istack', name: 'istack-commons-runtime', version: '3.0.11')
         api(group: 'com.sun.mail', name: 'javax.mail', version: '1.6.2')
         api(group: 'com.sun.xml.bind', name: 'jaxb-impl', version: '2.3.2')
-        api(group: 'com.tngtech.archunit', name:'archunit-junit4', version: '0.12.0')
+        api(group: 'com.tngtech.archunit', name: 'archunit-junit4', version: '0.12.0')
         api(group: 'com.zaxxer', name: 'HikariCP', version: '3.4.2')
         api(group: 'commons-beanutils', name: 'commons-beanutils', version: '1.9.4')
         api(group: 'commons-codec', name: 'commons-codec', version: '1.14')
@@ -172,6 +172,7 @@ class DependencyConstraints implements Plugin<Project> {
         api(group: 'pl.pragmatists', name: 'JUnitParams', version: '1.1.0')
         api(group: 'redis.clients', name: 'jedis', version: '3.2.0')
         api(group: 'xerces', name: 'xercesImpl', version: '2.12.0')
+        api(group: 'org.graphstream', name: 'gs-core', version: '1.3')
       }
     }
 
diff --git a/extensions/geode-modules-session/build.gradle b/extensions/geode-modules-session/build.gradle
index fd2d1f7..31aefd7 100644
--- a/extensions/geode-modules-session/build.gradle
+++ b/extensions/geode-modules-session/build.gradle
@@ -43,6 +43,8 @@ dependencies {
     exclude group: 'jboss'
     exclude group: 'xerces'
   }
+
+  integrationTestImplementation(project(':geode-common-services'))
   integrationTestImplementation('commons-io:commons-io')
   integrationTestImplementation('javax.servlet:javax.servlet-api')
   integrationTestImplementation('junit:junit')
diff --git a/extensions/geode-modules-test/build.gradle b/extensions/geode-modules-test/build.gradle
index 936c5f6..76c1471 100644
--- a/extensions/geode-modules-test/build.gradle
+++ b/extensions/geode-modules-test/build.gradle
@@ -53,5 +53,7 @@ dependencies {
     exclude module: 'annotations-api'
     exclude module: 'tribes'
   }
+
+  testImplementation(project(':geode-common-services'))
 }
 
diff --git a/extensions/geode-modules-tomcat7/build.gradle b/extensions/geode-modules-tomcat7/build.gradle
index d2c5fdc..6f61b0c 100644
--- a/extensions/geode-modules-tomcat7/build.gradle
+++ b/extensions/geode-modules-tomcat7/build.gradle
@@ -29,6 +29,7 @@ dependencies {
   compile(project(':geode-core'))
   implementation('mx4j:mx4j')
   implementation('javax.servlet:javax.servlet-api')
+  integrationTestImplementation(project(':geode-common-services'))
   integrationTestImplementation('org.httpunit:httpunit')
   integrationTestImplementation('junit:junit')
   compile(project(':extensions:geode-modules')) {
@@ -49,6 +50,7 @@ dependencies {
   }
   implementation('org.apache.tomcat:tomcat-juli:' + DependencyConstraints.get('tomcat7.version'))
 
+  testImplementation(project(':geode-common-services'))
   testImplementation('org.httpunit:httpunit')
   testImplementation('junit:junit')
   testImplementation('org.assertj:assertj-core')
@@ -57,6 +59,8 @@ dependencies {
   integrationTestImplementation(project(':geode-dunit')) {
     exclude module: 'geode-core'
   }
+
+  integrationTestImplementation(project(':geode-common-services'))
   integrationTestImplementation(project(':extensions:geode-modules-test'))
 
   integrationTestRuntimeOnly('javax.annotation:jsr250-api')
diff --git a/extensions/geode-modules-tomcat8/build.gradle b/extensions/geode-modules-tomcat8/build.gradle
index 3a8d665..fa9470b 100644
--- a/extensions/geode-modules-tomcat8/build.gradle
+++ b/extensions/geode-modules-tomcat8/build.gradle
@@ -62,6 +62,10 @@ dependencies {
     implementation('org.apache.tomcat:tomcat-juli:' + DependencyConstraints.get('tomcat8.version'))
     implementation('javax.servlet:javax.servlet-api')
 
+    testImplementation(project(':geode-common-services'))
+
+    integrationTestImplementation(project(':geode-common-services'))
+
     integrationTestImplementation(project(':geode-dunit')) {
         exclude module: 'geode-core'
     }
diff --git a/extensions/geode-modules-tomcat9/build.gradle b/extensions/geode-modules-tomcat9/build.gradle
index dea8c30..fd613c3 100644
--- a/extensions/geode-modules-tomcat9/build.gradle
+++ b/extensions/geode-modules-tomcat9/build.gradle
@@ -39,6 +39,7 @@ dependencies {
   implementation('org.apache.tomcat:tomcat-juli:' + DependencyConstraints.get('tomcat9.version'))
   implementation('javax.servlet:javax.servlet-api:4.0.1')
 
+  testImplementation(project(':geode-common-services'))
   testImplementation('org.httpunit:httpunit')
   testImplementation('junit:junit')
   testImplementation('org.assertj:assertj-core')
diff --git a/extensions/geode-modules/build.gradle b/extensions/geode-modules/build.gradle
index 7210d11..52a6e12 100644
--- a/extensions/geode-modules/build.gradle
+++ b/extensions/geode-modules/build.gradle
@@ -31,6 +31,7 @@ dependencies {
   integrationTestImplementation(project(':extensions:geode-modules-test')) {
     exclude module: 'geode-modules'
   }
+  testImplementation(project(':geode-common-services'))
   testImplementation(project(':extensions:geode-modules-test')) {
     exclude module: 'geode-modules'
   }
@@ -59,6 +60,7 @@ dependencies {
   testImplementation('org.mockito:mockito-core')
 
 
+  integrationTestImplementation(project(':geode-common-services'))
   integrationTestImplementation('junit:junit')
   integrationTestImplementation('pl.pragmatists:JUnitParams')
 
diff --git a/geode-assembly/build.gradle b/geode-assembly/build.gradle
index f40a908..d4ebd5b 100755
--- a/geode-assembly/build.gradle
+++ b/geode-assembly/build.gradle
@@ -27,47 +27,49 @@ import java.nio.file.Paths
 
 // This list is used in a loop to defined the /lib copySpec
 def dependentProjectNames = [
-  ':geode-common',
-  ':geode-common-services',
-  ':geode-connectors',
-  ':geode-core',
-  ':geode-cq',
-  ':geode-gfsh',
-  ':geode-log4j',
-  ':geode-logging',
-  ':geode-lucene',
-  ':geode-memcached',
-  ':geode-modules',
-  ':geode-old-client-support',
-  ':geode-protobuf',
-  ':geode-protobuf-messages',
-  ':geode-rebalancer',
-  ':geode-redis',
-  ':geode-serialization',
-  ':geode-tcp-server',
-  ':geode-wan'
+        ':geode-common',
+        ':geode-common-services',
+        ':geode-connectors',
+        ':geode-core',
+        ':geode-cq',
+        ':geode-gfsh',
+        ':geode-log4j',
+        ':geode-logging',
+        ':geode-lucene',
+        ':geode-memcached',
+        ':geode-modules',
+        ':geode-old-client-support',
+        ':geode-protobuf',
+        ':geode-protobuf-messages',
+        ':geode-rebalancer',
+        ':geode-redis',
+        ':geode-serialization',
+        ':geode-tcp-server',
+        ':geode-wan',
+        ':geode-module-management',
+        ':geode-module-bootstrapping'
 ]
 
 // These other dependencies are explicitly referenced throughout other copySpec
 def otherDependentProjectNames = [
-  ':extensions:geode-modules',
-  ':extensions:geode-modules-assembly',
-  ':extensions:geode-modules-session',
-  ':extensions:geode-modules-session',
-  ':extensions:geode-modules-tomcat7',
-  ':extensions:geode-modules-tomcat8',
-  ':extensions:geode-modules-tomcat9',
-  ':geode-experimental-driver',
-  ':geode-management',
-  ':geode-pulse',
-  ':geode-web',
-  ':geode-web-api',
-  ':geode-web-management',
+        ':extensions:geode-modules',
+        ':extensions:geode-modules-assembly',
+        ':extensions:geode-modules-session',
+        ':extensions:geode-modules-session',
+        ':extensions:geode-modules-tomcat7',
+        ':extensions:geode-modules-tomcat8',
+        ':extensions:geode-modules-tomcat9',
+        ':geode-experimental-driver',
+        ':geode-management',
+        ':geode-pulse',
+        ':geode-web',
+        ':geode-web-api',
+        ':geode-web-management',
 ]
 
 evaluationDependsOnChildren()
 (dependentProjectNames + otherDependentProjectNames).each { neighborProjectName ->
-  project.evaluationDependsOn(neighborProjectName)
+    project.evaluationDependsOn(neighborProjectName)
 }
 
 apply plugin: 'distribution'
@@ -79,242 +81,250 @@ apply from: "${rootDir}/${scriptDir}/publish-common.gradle"
 // in the geode-all-bom.
 project.ext.set('constrainVersionInBom', false)
 
-project.ext {artifactName = 'apache-geode'}
+project.ext { artifactName = 'apache-geode' }
 
 configurations {
-  compositeTarget {
-    setDescription("Composite builds wishing to consume this apache-geode@tgz artifact must specify \"targetConfiguration = 'compositeTarget'\" for correct composite task dependency detection.")
-  }
-
-  gfshDependencies
-
-  // Configurations used to download and cache web application servers for session module testing
-  webServerTomcat6
-  webServerTomcat7
-  webServerTomcat8
-  webServerTomcat9
-  webServerJetty
-
-  geodeArchives {
-    setDescription("An 'archives' configuration without the legacy publication implications")
-  }
-
-  javadocOnly {
-    setDescription('Projects that must be included in the JavaDocs.')
-    extendsFrom geodeArchives
-  }
+    compositeTarget {
+        setDescription("Composite builds wishing to consume this apache-geode@tgz artifact must specify \"targetConfiguration = 'compositeTarget'\" for correct composite task dependency detection.")
+    }
+
+    gfshDependencies
+
+    // Configurations used to download and cache web application servers for session module testing
+    webServerTomcat6
+    webServerTomcat7
+    webServerTomcat8
+    webServerTomcat9
+    webServerJetty
+
+    geodeArchives {
+        setDescription("An 'archives' configuration without the legacy publication implications")
+    }
+
+    javadocOnly {
+        setDescription('Projects that must be included in the JavaDocs.')
+        extendsFrom geodeArchives
+    }
 }
 
 publishing {
-  publications {
-    maven(MavenPublication) {
-      artifactId = artifactName
-      artifact source: distTar, extension: 'tgz'
+    publications {
+        maven(MavenPublication) {
+            artifactId = artifactName
+            artifact source: distTar, extension: 'tgz'
+        }
     }
-  }
 }
 
-gradle.taskGraph.whenReady( { graph ->
-  tasks.withType(AbstractArchiveTask).findAll {
-    it.name.toLowerCase().contains("dist")
-  }.each { archive ->
-    archive.doLast {
-      ant.checksum file:"${archive.archivePath}", algorithm:"sha-256", format: 'MD5SUM', fileext: '.sha256'
+gradle.taskGraph.whenReady({ graph ->
+    tasks.withType(AbstractArchiveTask).findAll {
+        it.name.toLowerCase().contains("dist")
+    }.each { archive ->
+        archive.doLast {
+            ant.checksum file: "${archive.archivePath}", algorithm: "sha-256", format: 'MD5SUM', fileext: '.sha256'
+        }
     }
-  }
 })
 
 artifacts {
-  compositeTarget distTar
+    compositeTarget distTar
 }
 
 //This "repository" only exists to download tomcat-6, because the zip for tomcat 6 is
 //not in a maven repo. Later versions of tomcat are.
 repositories {
-  ivy {
-    url 'https://archive.apache.org/'
-    patternLayout {
-      artifact '/dist/tomcat/tomcat-6/v6.0.37/bin/[organisation]-[module]-[revision].[ext]'
-    }
-  }
-  // For gradle tooling dependencies
-  maven {
-    url 'https://repo.gradle.org/gradle/libs-releases'
-  }
-  // docker-compose-rule is published on bintray
-  maven {
-    url 'https://dl.bintray.com/palantir/releases'
-  }
+    ivy {
+        url 'https://archive.apache.org/'
+        patternLayout {
+            artifact '/dist/tomcat/tomcat-6/v6.0.37/bin/[organisation]-[module]-[revision].[ext]'
+        }
+    }
+    // For gradle tooling dependencies
+    maven {
+        url 'https://repo.gradle.org/gradle/libs-releases'
+    }
+    // docker-compose-rule is published on bintray
+    maven {
+        url 'https://dl.bintray.com/palantir/releases'
+    }
 }
 
 def webServersDir = "$buildDir/generated-resources/webservers"
 
 sourceSets {
-  distributedTest {
-    resources {
-      srcDirs webServersDir
+    distributedTest {
+        resources {
+            srcDirs webServersDir
+        }
+        output.dir(webServersDir, builtBy: 'downloadWebServers')
     }
-    output.dir(webServersDir, builtBy: 'downloadWebServers')
-  }
 }
 
-task downloadWebServers(type:Copy) {
-  from {configurations.findAll {it.name.startsWith("webServer")}}
-  into webServersDir
+task downloadWebServers(type: Copy) {
+    from { configurations.findAll { it.name.startsWith("webServer") } }
+    into webServersDir
 }
 
 dependencies {
-  compile(platform(project(':boms:geode-all-bom')))
-  gfshDependencies(platform(project(':boms:geode-all-bom')))
-
-  dependentProjectNames.each {
-    geodeArchives(project(it))
-  }
-  geodeArchives project(':geode-management')
-  geodeArchives project(path: ':geode-web', configuration: 'war')
-  geodeArchives project(path: ':geode-web-api', configuration: 'war')
-  geodeArchives project(path: ':geode-web-management', configuration: 'war')
-
-  javadocOnly project(':extensions:geode-modules')
-  javadocOnly project(':extensions:geode-modules-session')
-  javadocOnly project(':extensions:geode-modules-session')
-  javadocOnly project(':extensions:geode-modules-tomcat7')
-  javadocOnly project(':extensions:geode-modules-tomcat9')
-  javadocOnly project(':extensions:geode-modules-tomcat8')
-  javadocOnly project(':geode-experimental-driver')
-
-  testImplementation(project(':geode-core'))
-  testImplementation(project(':geode-gfsh'))
-  testImplementation(project(':geode-junit')) {
-    exclude module: 'geode-core'
-  }
-  testImplementation(project(':geode-log4j')) {
-    exclude module: 'geode-core'
-  }
-
-  acceptanceTestRuntimeOnly(project(path: ':geode-old-versions', configuration: 'testOutput'))
-
-  integrationTestImplementation(project(':geode-core'))
-  integrationTestImplementation(project(':geode-gfsh'))
-  integrationTestImplementation(project(':geode-log4j')) {
-    exclude module: 'geode-core'
-  }
-  integrationTestImplementation(project(':geode-junit')) {
-    exclude module: 'geode-core'
-  }
-  integrationTestImplementation(project(':geode-dunit')) {
-    exclude module: 'geode-core'
-  }
-  integrationTestImplementation(project(':geode-pulse'))
-  integrationTestImplementation(project(':geode-assembly:geode-assembly-test'))
-  integrationTestImplementation(project(':geode-logging'))
-  integrationTestImplementation('org.apache.httpcomponents:httpclient')
-  integrationTestImplementation('org.springframework:spring-beans')
-  integrationTestImplementation('org.springframework:spring-context')
-  integrationTestImplementation('org.springframework:spring-web')
-  integrationTestImplementation('org.springframework.security:spring-security-oauth2-core')
-  integrationTestImplementation('org.springframework.security:spring-security-oauth2-client')
-  integrationTestImplementation('org.springframework.security:spring-security-oauth2-jose')
-  integrationTestImplementation('javax.annotation:javax.annotation-api')
-  integrationTestImplementation('javax.servlet:javax.servlet-api')
+    compile(platform(project(':boms:geode-all-bom')))
+    gfshDependencies(platform(project(':boms:geode-all-bom')))
+
+    dependentProjectNames.each {
+        geodeArchives(project(it))
+    }
+    geodeArchives project(':geode-management')
+    geodeArchives project(path: ':geode-web', configuration: 'war')
+    geodeArchives project(path: ':geode-web-api', configuration: 'war')
+    geodeArchives project(path: ':geode-web-management', configuration: 'war')
+
+    javadocOnly project(':extensions:geode-modules')
+    javadocOnly project(':extensions:geode-modules-session')
+    javadocOnly project(':extensions:geode-modules-session')
+    javadocOnly project(':extensions:geode-modules-tomcat7')
+    javadocOnly project(':extensions:geode-modules-tomcat9')
+    javadocOnly project(':extensions:geode-modules-tomcat8')
+    javadocOnly project(':geode-experimental-driver')
+
+    testImplementation(project(':geode-common-services'))
+    testImplementation(project(':geode-core'))
+    testImplementation(project(':geode-gfsh'))
+    testImplementation(project(':geode-junit')) {
+        exclude module: 'geode-core'
+    }
+    testImplementation(project(':geode-log4j')) {
+        exclude module: 'geode-core'
+    }
+    testRuntime(project(path: ':geode-old-versions', configuration: 'testOutput'))
+
+
+    acceptanceTestRuntimeOnly(project(path: ':geode-old-versions', configuration: 'testOutput'))
+
+
+    integrationTestImplementation(project(':geode-common-services'))
+    integrationTestImplementation(project(':geode-core'))
+    integrationTestImplementation(project(':geode-gfsh'))
+    integrationTestImplementation(project(':geode-log4j')) {
+        exclude module: 'geode-core'
+    }
+    integrationTestImplementation(project(':geode-junit')) {
+        exclude module: 'geode-core'
+    }
+    integrationTestImplementation(project(':geode-dunit')) {
+        exclude module: 'geode-core'
+    }
+    integrationTestImplementation(project(':geode-pulse'))
+    integrationTestImplementation(project(':geode-assembly:geode-assembly-test'))
+    integrationTestImplementation(project(':geode-logging'))
+    integrationTestImplementation('org.apache.httpcomponents:httpclient')
+    integrationTestImplementation('org.springframework:spring-beans')
+    integrationTestImplementation('org.springframework:spring-context')
+    integrationTestImplementation('org.springframework:spring-web')
+    integrationTestImplementation('org.springframework.security:spring-security-oauth2-core')
+    integrationTestImplementation('org.springframework.security:spring-security-oauth2-client')
+    integrationTestImplementation('org.springframework.security:spring-security-oauth2-jose')
+    integrationTestImplementation('javax.annotation:javax.annotation-api')
+    integrationTestImplementation('javax.servlet:javax.servlet-api')
 
   integrationTestRuntime(project(path: ':geode-old-versions', configuration: 'testOutput'))
 
-  integrationTestRuntimeOnly('io.swagger:swagger-annotations')
-  // these two modules are for testing only
-  integrationTestRuntimeOnly('com.fasterxml.jackson.datatype:jackson-datatype-joda')
-  integrationTestRuntimeOnly('joda-time:joda-time')
-
-  distributedTestCompileOnly(platform(project(':boms:geode-all-bom')))
-  distributedTestCompileOnly('io.swagger:swagger-annotations')
-  distributedTestImplementation(project(':geode-gfsh'))
-  distributedTestImplementation(project(':geode-logging'))
-  distributedTestImplementation(project(':geode-membership'))
-  distributedTestImplementation(project(':geode-serialization'))
-  distributedTestImplementation(project(':geode-tcp-server'))
-  distributedTestImplementation(project(':geode-core'))
-  distributedTestImplementation(project(':geode-log4j')) {
-    exclude module: 'geode-core'
-  }
-  distributedTestImplementation(project(':geode-dunit')){
-    exclude module: 'geode-core'
-  }
-  distributedTestImplementation(project(':extensions:session-testing-war'))
-  distributedTestImplementation(project(':geode-assembly:geode-assembly-test'))
-  distributedTestImplementation('org.apache.httpcomponents:httpclient')
-  distributedTestImplementation('org.springframework:spring-web')
-  distributedTestImplementation(project(':geode-management'))
-  distributedTestImplementation(project(':geode-web-management'))
-  distributedTestImplementation('com.arakelian:java-jq')
-  distributedTestImplementation('javax.servlet:javax.servlet-api')
-
-  distributedTestRuntimeOnly(project(':extensions:geode-modules-session-internal')) {
-    exclude group: 'org.apache.tomcat'
-  }
-  distributedTestRuntimeOnly('org.codehaus.cargo:cargo-core-uberjar')
-  distributedTestRuntimeOnly('io.swagger:swagger-annotations')
-  distributedTestRuntimeOnly(project(':geode-wan'))
-
-  // geodeArchives is a direct reflection of what is contained in geode-dependencies.jar. To that
-  // end only add _test_ dependencies to acceptanceTestCompile/Runtime. All other product
-  // dependencies should be a part of geodeArchives and should not need to be added as individual
-  // dependencies here.
-  acceptanceTestImplementation(configurations.geodeArchives)
-  acceptanceTestImplementation(project(':geode-dunit')) {
-    exclude module: 'geode-core'
-  }
-  acceptanceTestImplementation(project(':geode-assembly:geode-assembly-test'))
-
-  // This is used by 'gradle within gradle' tests. No need to bump this version; but if you do,
-  // don't have it be the same version as the outer gradle version.
-  acceptanceTestImplementation('org.gradle:gradle-tooling-api:5.1.1')
-
-  acceptanceTestImplementation('com.palantir.docker.compose:docker-compose-rule-core')
-  acceptanceTestImplementation('com.palantir.docker.compose:docker-compose-rule-junit4')
-
-  uiTestImplementation(project(':geode-core'))
-  uiTestImplementation(project(':geode-dunit')) {
-    exclude module: 'geode-core'
-  }
-  uiTestImplementation(project(':geode-pulse'))
-  uiTestImplementation(project(':geode-pulse:geode-pulse-test'))
-  uiTestImplementation(project(':geode-assembly:geode-assembly-test'))
-  uiTestImplementation('org.seleniumhq.selenium:selenium-api')
-  uiTestImplementation('org.seleniumhq.selenium:selenium-remote-driver')
-  uiTestImplementation('org.seleniumhq.selenium:selenium-support')
-
-  uiTestRuntimeOnly(project(':geode-core'))
-  uiTestRuntimeOnly('org.seleniumhq.selenium:selenium-chrome-driver')
-
-  upgradeTestImplementation(project(':geode-gfsh'))
-  upgradeTestImplementation(project(':geode-logging'))
-  upgradeTestImplementation(project(':geode-serialization'))
-  upgradeTestImplementation(project(':geode-core'))
-  upgradeTestImplementation(project(':geode-dunit')) {
-    exclude module: 'geode-core'
-  }
-  upgradeTestImplementation(project(':geode-assembly:geode-assembly-test'))
-
-  upgradeTestCompileOnly(platform(project(':boms:geode-all-bom')))
-  upgradeTestCompileOnly('io.swagger:swagger-annotations')
-
-  upgradeTestRuntimeOnly(project(path: ':geode-old-versions', configuration: 'testOutput'))
-  upgradeTestRuntimeOnly(project(':extensions:session-testing-war'))
-  upgradeTestRuntimeOnly('org.codehaus.cargo:cargo-core-uberjar')
-  upgradeTestRuntimeOnly('org.apache.httpcomponents:httpclient')
-  upgradeTestRuntime files({ downloadWebServers } )
-
-  //Web servers used for session module testing
-  webServerTomcat6('apache:tomcat:' + DependencyConstraints.get('tomcat6.version') + '@zip')
-  webServerTomcat7('org.apache.tomcat:tomcat:' + DependencyConstraints.get('tomcat7.version') + '@zip')
-  webServerTomcat8('org.apache.tomcat:tomcat:' + DependencyConstraints.get('tomcat8.version') + '@zip')
-  webServerTomcat9('org.apache.tomcat:tomcat:' + DependencyConstraints.get('tomcat9.version') + '@zip')
-  webServerJetty('org.eclipse.jetty:jetty-distribution:' + DependencyConstraints.get('jetty.version') + '@zip')
-
-  gfshDependencies ('org.springframework:spring-web') {
-    exclude module: 'spring-core'
-    exclude module: 'commons-logging'
-  }
+    integrationTestRuntimeOnly('io.swagger:swagger-annotations')
+    // these two modules are for testing only
+    integrationTestRuntimeOnly('com.fasterxml.jackson.datatype:jackson-datatype-joda')
+    integrationTestRuntimeOnly('joda-time:joda-time')
+
+
+    distributedTestImplementation(project(':geode-common-services'))
+    distributedTestCompileOnly(platform(project(':boms:geode-all-bom')))
+    distributedTestCompileOnly('io.swagger:swagger-annotations')
+    distributedTestImplementation(project(':geode-gfsh'))
+    distributedTestImplementation(project(':geode-logging'))
+    distributedTestImplementation(project(':geode-membership'))
+    distributedTestImplementation(project(':geode-serialization'))
+    distributedTestImplementation(project(':geode-tcp-server'))
+    distributedTestImplementation(project(':geode-core'))
+    distributedTestImplementation(project(':geode-log4j')) {
+        exclude module: 'geode-core'
+    }
+    distributedTestImplementation(project(':geode-dunit')) {
+        exclude module: 'geode-core'
+    }
+    distributedTestImplementation(project(':extensions:session-testing-war'))
+    distributedTestImplementation(project(':geode-assembly:geode-assembly-test'))
+    distributedTestImplementation('org.apache.httpcomponents:httpclient')
+    distributedTestImplementation('org.springframework:spring-web')
+    distributedTestImplementation(project(':geode-management'))
+    distributedTestImplementation(project(':geode-web-management'))
+    distributedTestImplementation('com.arakelian:java-jq')
+    distributedTestImplementation('javax.servlet:javax.servlet-api')
+
+    distributedTestRuntimeOnly(project(':extensions:geode-modules-session-internal')) {
+        exclude group: 'org.apache.tomcat'
+    }
+    distributedTestRuntimeOnly('org.codehaus.cargo:cargo-core-uberjar')
+    distributedTestRuntimeOnly('io.swagger:swagger-annotations')
+    distributedTestRuntimeOnly(project(':geode-wan'))
+
+
+    // geodeArchives is a direct reflection of what is contained in geode-dependencies.jar. To that
+    // end only add _test_ dependencies to acceptanceTestCompile/Runtime. All other product
+    // dependencies should be a part of geodeArchives and should not need to be added as individual
+    // dependencies here.
+    acceptanceTestImplementation(configurations.geodeArchives)
+    acceptanceTestImplementation(project(':geode-dunit')) {
+        exclude module: 'geode-core'
+    }
+    acceptanceTestImplementation(project(':geode-assembly:geode-assembly-test'))
+
+    // This is used by 'gradle within gradle' tests. No need to bump this version; but if you do,
+    // don't have it be the same version as the outer gradle version.
+    acceptanceTestImplementation('org.gradle:gradle-tooling-api:5.1.1')
+
+    acceptanceTestImplementation('com.palantir.docker.compose:docker-compose-rule-core')
+    acceptanceTestImplementation('com.palantir.docker.compose:docker-compose-rule-junit4')
+
+    uiTestImplementation(project(':geode-core'))
+    uiTestImplementation(project(':geode-dunit')) {
+        exclude module: 'geode-core'
+    }
+    uiTestImplementation(project(':geode-pulse'))
+    uiTestImplementation(project(':geode-pulse:geode-pulse-test'))
+    uiTestImplementation(project(':geode-assembly:geode-assembly-test'))
+    uiTestImplementation('org.seleniumhq.selenium:selenium-api')
+    uiTestImplementation('org.seleniumhq.selenium:selenium-remote-driver')
+    uiTestImplementation('org.seleniumhq.selenium:selenium-support')
+
+    uiTestRuntimeOnly(project(':geode-core'))
+    uiTestRuntimeOnly('org.seleniumhq.selenium:selenium-chrome-driver')
+
+    upgradeTestImplementation(project(':geode-gfsh'))
+    upgradeTestImplementation(project(':geode-logging'))
+    upgradeTestImplementation(project(':geode-serialization'))
+    upgradeTestImplementation(project(':geode-core'))
+    upgradeTestImplementation(project(':geode-dunit')) {
+        exclude module: 'geode-core'
+    }
+    upgradeTestImplementation(project(':geode-assembly:geode-assembly-test'))
+
+    upgradeTestCompileOnly(platform(project(':boms:geode-all-bom')))
+    upgradeTestCompileOnly('io.swagger:swagger-annotations')
+
+    upgradeTestRuntimeOnly(project(path: ':geode-old-versions', configuration: 'testOutput'))
+    upgradeTestRuntimeOnly(project(':extensions:session-testing-war'))
+    upgradeTestRuntimeOnly('org.codehaus.cargo:cargo-core-uberjar')
+    upgradeTestRuntimeOnly('org.apache.httpcomponents:httpclient')
+    upgradeTestRuntime files({ downloadWebServers })
+
+    //Web servers used for session module testing
+    webServerTomcat6('apache:tomcat:' + DependencyConstraints.get('tomcat6.version') + '@zip')
+    webServerTomcat7('org.apache.tomcat:tomcat:' + DependencyConstraints.get('tomcat7.version') + '@zip')
+    webServerTomcat8('org.apache.tomcat:tomcat:' + DependencyConstraints.get('tomcat8.version') + '@zip')
+    webServerTomcat9('org.apache.tomcat:tomcat:' + DependencyConstraints.get('tomcat9.version') + '@zip')
+    webServerJetty('org.eclipse.jetty:jetty-distribution:' + DependencyConstraints.get('jetty.version') + '@zip')
+
+    gfshDependencies('org.springframework:spring-web') {
+        exclude module: 'spring-core'
+        exclude module: 'commons-logging'
+    }
 }
 
 acceptanceTest {
@@ -323,298 +333,301 @@ acceptanceTest {
 }
 
 tasks.register('defaultDistributionConfig', JavaExec) {
-  inputs.files {
-    project(':geode-core').sourceSets.main.runtimeClasspath
-  }
-  outputs.file file("$buildDir/gemfire.properties")
-  main 'org.apache.geode.distributed.internal.DefaultPropertiesGenerator'
-  classpath project(':geode-core').sourceSets.main.runtimeClasspath
-  workingDir buildDir
-
-  doFirst {
-    buildDir.mkdirs()
-  }
+    inputs.files {
+        project(':geode-core').sourceSets.main.runtimeClasspath
+    }
+    outputs.file file("$buildDir/gemfire.properties")
+    main 'org.apache.geode.distributed.internal.DefaultPropertiesGenerator'
+    classpath project(':geode-core').sourceSets.main.runtimeClasspath
+    workingDir buildDir
+
+    doFirst {
+        buildDir.mkdirs()
+    }
 }
 
 tasks.register('defaultCacheConfig', JavaExec) {
-  inputs.files {
-    project(':geode-core').sourceSets.main.runtimeClasspath
-  }
-  outputs.file file("$buildDir/cache.xml")
-  main 'org.apache.geode.internal.cache.xmlcache.CacheXmlGenerator'
-  classpath project(':geode-core').sourceSets.main.runtimeClasspath
-  workingDir buildDir
-
-  doFirst {
-    buildDir.mkdirs()
-  }
+    inputs.files {
+        project(':geode-core').sourceSets.main.runtimeClasspath
+    }
+    outputs.file file("$buildDir/cache.xml")
+    main 'org.apache.geode.internal.cache.xmlcache.CacheXmlGenerator'
+    classpath project(':geode-core').sourceSets.main.runtimeClasspath
+    workingDir buildDir
+
+    doFirst {
+        buildDir.mkdirs()
+    }
 }
 
 // This closure sets the geode classpath.  If we add another jar to the classpath it must
 // be included in the filter logic below.
 def cp = {
-  // first add all the dependent project jars
-  def jars = configurations.geodeArchives.dependencies.collect { it.dependencyProject }
-    .findAll { !(it.name.contains('geode-web') || it.name.contains('geode-pulse')) }
-    .collect { it.jar.archiveName }
-
-  // then add all the dependencies of the dependent jars
-  def depJars = configurations.geodeArchives.dependencies.collect {
-    it.dependencyProject.findAll {
-      !(it.name.contains('geode-web') ||
-        it.name.contains('geode-pulse'))
-    }.collect {
-      it.configurations.runtimeClasspath.collect { it.getName() }.findAll { !(
-          it.contains('geode-all-bom') ||
-
-            // exclude mx4j, once the deprecated code is deleted we can remove these entirely
-            it.contains('commons-digester') ||
-            it.contains('commons-modeler') ||
-            it.contains('javax.mail-api') ||
-            it.contains('mx4j') ||
-
-            // misc jars, these should be removed from the lib dir
-            it.contains('findbugs-annotations') ||
-            it.contains('geode-dependencies') ||
-            it.contains('geode-jca') ||
-            it.contains('geode-web') ||
-            it.contains('gfsh-dependencies') ||
-            it.contains('ra.jar') ||
-
-            // spring web deps that shouldn't be here either
-            it.contains('spring-aop') ||
-            it.contains('spring-beans') ||
-            it.contains('spring-context') ||
-            it.contains('spring-expression') ||
-            it.contains('spring-web')
-        )}
-    }
-  }.flatten()
-
-  return jars.plus(depJars).unique().join(' ')
+    // first add all the dependent project jars
+    def jars = configurations.geodeArchives.dependencies.collect { it.dependencyProject }
+            .findAll { !(it.name.contains('geode-web') || it.name.contains('geode-pulse')) }
+            .collect { it.jar.archiveName }
+
+    // then add all the dependencies of the dependent jars
+    def depJars = configurations.geodeArchives.dependencies.collect {
+        it.dependencyProject.findAll {
+            !(it.name.contains('geode-web') ||
+                    it.name.contains('geode-pulse'))
+        }.collect {
+            it.configurations.runtimeClasspath.collect { it.getName() }.findAll {
+                !(
+                        it.contains('geode-all-bom') ||
+
+                                // exclude mx4j, once the deprecated code is deleted we can remove these entirely
+                                it.contains('commons-digester') ||
+                                it.contains('commons-modeler') ||
+                                it.contains('javax.mail-api') ||
+                                it.contains('mx4j') ||
+
+                                // misc jars, these should be removed from the lib dir
+                                it.contains('findbugs-annotations') ||
+                                it.contains('geode-dependencies') ||
+                                it.contains('geode-jca') ||
+                                it.contains('geode-web') ||
+                                it.contains('gfsh-dependencies') ||
+                                it.contains('ra.jar') ||
+
+                                // spring web deps that shouldn't be here either
+                                it.contains('spring-aop') ||
+                                it.contains('spring-beans') ||
+                                it.contains('spring-context') ||
+                                it.contains('spring-expression') ||
+                                it.contains('spring-web')
+                )
+            }
+        }
+    }.flatten()
+
+    return jars.plus(depJars).unique().join(' ')
 }
 
 tasks.register('configureDepsJar') {
-  inputs.files {
-    configurations.geodeArchives
-  }
-
-  def output = project.buildDir.toPath().resolve('reports').resolve('deps_jar_cp.txt')
-  outputs.file {
-    output
-  }
-  doLast {
-    output.write(cp())
-  }
+    inputs.files {
+        configurations.geodeArchives
+    }
+
+    def output = project.buildDir.toPath().resolve('reports').resolve('deps_jar_cp.txt')
+    outputs.file {
+        output
+    }
+    doLast {
+        output.write(cp())
+    }
 }
 
 tasks.register('configureGfshDepsJar') {
-  inputs.files {
-    configurations.gfshDependencies
-  }
-
-  inputs.files {
-    configureDepsJar
-  }
-
-  def output = project.buildDir.toPath().resolve('reports').resolve('gfsh_deps_jar_cp.txt')
-  outputs.file {
-    output
-  }
-  doLast {
-    def classpath = configureDepsJar.outputs.files.singleFile.text + ' ' +
-        configurations.gfshDependencies.collect { it.getName() }.findAll {
-          !it.contains('geode-all-bom')
-        }.flatten().unique().join(' ')
-    output.write(classpath)
-  }
+    inputs.files {
+        configurations.gfshDependencies
+    }
+
+    inputs.files {
+        configureDepsJar
+    }
+
+    def output = project.buildDir.toPath().resolve('reports').resolve('gfsh_deps_jar_cp.txt')
+    outputs.file {
+        output
+    }
+    doLast {
+        def classpath = configureDepsJar.outputs.files.singleFile.text + ' ' +
+                configurations.gfshDependencies.collect { it.getName() }.findAll {
+                    !it.contains('geode-all-bom')
+                }.flatten().unique().join(' ')
+        output.write(classpath)
+    }
 }
 
 // Configure the manifest contents in a separate always-running task to ensure correctness of
 // these dependency jars
 tasks.register('depsJar', Jar) {
-  inputs.files {
-    configureDepsJar
-  }
-  description 'Assembles the jar archive that defines the gemfire classpath.'
-  archiveName 'geode-dependencies.jar'
-  doFirst {
-    manifest {
-      attributes("Class-Path": configureDepsJar.outputs.files.singleFile.text)
-    }
-  }
+    inputs.files {
+        configureDepsJar
+    }
+    description 'Assembles the jar archive that defines the gemfire classpath.'
+    archiveName 'geode-dependencies.jar'
+    doFirst {
+        manifest {
+            attributes("Class-Path": configureDepsJar.outputs.files.singleFile.text)
+        }
+    }
 }
 
 tasks.register('gfshDepsJar', Jar) {
-  inputs.files {
-    configureGfshDepsJar
-  }
-  description 'Assembles the jar archive that defines the gfsh classpath.'
-  archiveName 'gfsh-dependencies.jar'
-  doFirst {
-    manifest {
-      attributes("Class-Path": configureGfshDepsJar.outputs.files.singleFile.text)
-    }
-  }
+    inputs.files {
+        configureGfshDepsJar
+    }
+    description 'Assembles the jar archive that defines the gfsh classpath.'
+    archiveName 'gfsh-dependencies.jar'
+    doFirst {
+        manifest {
+            attributes("Class-Path": configureGfshDepsJar.outputs.files.singleFile.text)
+        }
+    }
 }
 
 tasks.register('docs', Javadoc) {
-  def docsDir = file("$buildDir/javadocs")
-  options.addStringOption('Xdoclint:none', '-quiet')
-  options.links("https://lucene.apache.org/core/6_4_1/core/")
-  options.links("https://lucene.apache.org/core/6_4_1/queryparser/")
-  options.links("https://docs.oracle.com/javase/8/docs/api/")
-  options.encoding = 'UTF-8'
-  title = "${productName} ${project.version}"
-  destinationDir = docsDir
-
-  configurations.getByName("javadocOnly").allDependencies.each() { proj ->
-    proj.dependencyProject.tasks.withType(Javadoc).findAll { it.enabled }.each { javadocTask ->
-      source += javadocTask.source
-      classpath += javadocTask.classpath
-      excludes += javadocTask.excludes
-      includes += javadocTask.includes
-    }
-  }
-
-  include 'org/apache/geode/**/'
-
-  doLast {
-    rootProject.subprojects.each { project ->
-      copy {
-        if (project.hasProperty('sourceSets')) {
-          from project.sourceSets.main.resources.srcDirs
+    def docsDir = file("$buildDir/javadocs")
+    options.addStringOption('Xdoclint:none', '-quiet')
+    options.links("https://lucene.apache.org/core/6_4_1/core/")
+    options.links("https://lucene.apache.org/core/6_4_1/queryparser/")
+    options.links("https://docs.oracle.com/javase/8/docs/api/")
+    options.encoding = 'UTF-8'
+    title = "${productName} ${project.version}"
+    destinationDir = docsDir
+
+    configurations.getByName("javadocOnly").allDependencies.each() { proj ->
+        proj.dependencyProject.tasks.withType(Javadoc).findAll { it.enabled }.each { javadocTask ->
+            source += javadocTask.source
+            classpath += javadocTask.classpath
+            excludes += javadocTask.excludes
+            includes += javadocTask.includes
+        }
+    }
+
+    include 'org/apache/geode/**/'
+
+    doLast {
+        rootProject.subprojects.each { project ->
+            copy {
+                if (project.hasProperty('sourceSets')) {
+                    from project.sourceSets.main.resources.srcDirs
+                }
+                include 'javadoc-images/*'
+                into docsDir
+            }
         }
-        include 'javadoc-images/*'
-        into docsDir
-      }
     }
-  }
 }
 
 distributions {
-  src {
-    baseName = 'apache-geode'
-    contents {
-      from rootProject.tasks.writeBuildInfo
-      from (rootDir) {
-        exclude 'KEYS'
-        exclude '**/gradlew'
-        exclude '**/gradlew.bat'
-        exclude '**/gradle/wrapper/gradle-wrapper.jar'
-        exclude '**/.gradle'
-        exclude '**/.project'
-        exclude '**/.classpath'
-        exclude '**/.settings/**'
-        exclude '**/build-eclipse/**'
-        exclude '**/.idea/**'
-        exclude '**/*.iml'
-        exclude '**/*.ipr'
-        exclude '**/*.iws'
-        exclude '**/.travis.yml'
-        exclude '**/tags'
-
-        //These directories are generated on the jenkins server by gradle
-        exclude 'caches'
-        exclude 'daemon'
-        exclude 'native'
-        exclude 'wrapper'
-
-        // These exclude the 'build' and 'out' artifact directories from Gradle and IntelliJ for each project
-        exclude 'buildSrc/build'
-        exclude 'buildSrc/out'
-        rootProject.allprojects.each {
-          def relPath = Paths.get(rootDir.getPath()).relativize(Paths.get(it.projectDir.getPath()))
-          def relOut = relPath.resolve("out").toString()
-          def relBuild = relPath.resolve("build").toString()
-          exclude relOut
-          exclude relBuild
-        }
-      }
-    }
-  }
-  named('main') {
-    baseName = 'apache-geode'
-    contents {
-      duplicatesStrategy 'exclude'
-      exclude '*.asc'
-
-      exclude '*.asc'
-      exclude '*-sources.jar'
-      exclude '*-javadoc.jar'
-
-      from rootProject.file('README.md')
-
-      from "${projectDir}/src/main/dist/"
-
-      with copySpec {
-        into('config')
-        from {defaultCacheConfig}
-        from {defaultDistributionConfig}
-        from {
-          (project(':geode-log4j').sourceSets.main.resources.files.find {
-            it.name == 'log4j2.xml'
-          })
+    src {
+        baseName = 'apache-geode'
+        contents {
+            from rootProject.tasks.writeBuildInfo
+            from(rootDir) {
+                exclude 'KEYS'
+                exclude '**/gradlew'
+                exclude '**/gradlew.bat'
+                exclude '**/gradle/wrapper/gradle-wrapper.jar'
+                exclude '**/.gradle'
+                exclude '**/.project'
+                exclude '**/.classpath'
+                exclude '**/.settings/**'
+                exclude '**/build-eclipse/**'
+                exclude '**/.idea/**'
+                exclude '**/*.iml'
+                exclude '**/*.ipr'
+                exclude '**/*.iws'
+                exclude '**/.travis.yml'
+                exclude '**/tags'
+
+                //These directories are generated on the jenkins server by gradle
+                exclude 'caches'
+                exclude 'daemon'
+                exclude 'native'
+                exclude 'wrapper'
+
+                // These exclude the 'build' and 'out' artifact directories from Gradle and IntelliJ for each project
+                exclude 'buildSrc/build'
+                exclude 'buildSrc/out'
+                rootProject.allprojects.each {
+                    def relPath = Paths.get(rootDir.getPath()).relativize(Paths.get(it.projectDir.getPath()))
+                    def relOut = relPath.resolve("out").toString()
+                    def relBuild = relPath.resolve("build").toString()
+                    exclude relOut
+                    exclude relBuild
+                }
+            }
         }
-      }
-
-      with copySpec {
-        into('lib')
-        from { dependentProjectNames.collect {
-            [
-              project(':'.concat(it)).configurations.runtimeClasspath,
-              project(':'.concat(it)).configurations.archives.allArtifacts.files
-            ]
-          }.flatten()
+    }
+    named('main') {
+        baseName = 'apache-geode'
+        contents {
+            duplicatesStrategy 'exclude'
+            exclude '*.asc'
+
+            exclude '*.asc'
+            exclude '*-sources.jar'
+            exclude '*-javadoc.jar'
+
+            from rootProject.file('README.md')
+
+            from "${projectDir}/src/main/dist/"
+
+            with copySpec {
+                into('config')
+                from { defaultCacheConfig }
+                from { defaultDistributionConfig }
+                from {
+                    (project(':geode-log4j').sourceSets.main.resources.files.find {
+                        it.name == 'log4j2.xml'
+                    })
+                }
+            }
+
+            with copySpec {
+                into('lib')
+                from {
+                    dependentProjectNames.collect {
+                        [
+                                project(':'.concat(it)).configurations.runtimeClasspath,
+                                project(':'.concat(it)).configurations.archives.allArtifacts.files
+                        ]
+                    }.flatten()
+                }
+
+                from configurations.gfshDependencies
+
+                //These tasks are included as closures (wrapped in {}) because gradle may evaluate
+                //this CopySpec before it evaluates the geode-core build file.
+                from { project(':geode-core').tasks.named('raJar') }
+                from { project(':geode-core').tasks.named('jcaJar') }
+
+                // dependency jars
+                from tasks.named('depsJar')
+                from tasks.named('gfshDepsJar')
+            }
+
+            with copySpec {
+                into('tools/Extensions')
+
+                from { project(':geode-web').configurations.archives.allArtifacts.files }
+                from { project(':geode-web-api').configurations.archives.allArtifacts.files }
+                from { project(':geode-web-management').configurations.archives.allArtifacts.files }
+
+                exclude '*.jar'
+            }
+
+            with copySpec {
+                into('tools/ClientProtocol')
+                from { project(':geode-protobuf-messages').zip.outputs.files }
+            }
+
+            with copySpec {
+                into('javadoc')
+                from { docs }
+            }
+
+            with copySpec {
+                into('tools/Pulse')
+                from { project(':geode-pulse').configurations.archives.allArtifacts.files }
+            }
+
+            with copySpec {
+                into('tools/Modules')
+
+                from { project(':extensions:geode-modules-assembly').distTcServer }
+                from { project(':extensions:geode-modules-assembly').distTcServer30 }
+                from { project(':extensions:geode-modules-assembly').distTomcat }
+                from { project(':extensions:geode-modules-assembly').distAppServer }
+            }
         }
-
-        from configurations.gfshDependencies
-
-        //These tasks are included as closures (wrapped in {}) because gradle may evaluate
-        //this CopySpec before it evaluates the geode-core build file.
-        from {project(':geode-core').tasks.named('raJar')}
-        from {project(':geode-core').tasks.named('jcaJar')}
-
-        // dependency jars
-        from tasks.named('depsJar')
-        from tasks.named('gfshDepsJar')
-      }
-
-      with copySpec {
-        into('tools/Extensions')
-
-        from {project(':geode-web').configurations.archives.allArtifacts.files}
-        from {project(':geode-web-api').configurations.archives.allArtifacts.files}
-        from {project(':geode-web-management').configurations.archives.allArtifacts.files}
-
-        exclude '*.jar'
-      }
-
-      with copySpec {
-        into('tools/ClientProtocol')
-        from {project(':geode-protobuf-messages').zip.outputs.files}
-      }
-
-      with copySpec {
-        into('javadoc')
-        from { docs }
-      }
-
-      with copySpec {
-        into('tools/Pulse')
-        from {project(':geode-pulse').configurations.archives.allArtifacts.files}
-      }
-
-      with copySpec {
-        into('tools/Modules')
-
-        from { project(':extensions:geode-modules-assembly').distTcServer }
-        from { project(':extensions:geode-modules-assembly').distTcServer30 }
-        from { project(':extensions:geode-modules-assembly').distTomcat }
-        from { project(':extensions:geode-modules-assembly').distAppServer }
-      }
     }
-  }
 
 }
 // Distribution plugin does not allow configuring of the task, only the contents. So we set
@@ -622,27 +635,27 @@ distributions {
 [tasks.named('distTar'),
  tasks.named('srcDistTar'),
 ]*.configure {
-  compression Compression.GZIP
-  extension 'tgz'
-  build.dependsOn(it)
+    compression Compression.GZIP
+    extension 'tgz'
+    build.dependsOn(it)
 }
 // Make build final task to generate all test and product resources
 build.dependsOn(installDist)
 
 tasks.named('srcDistTar').configure {
-  classifier 'src'
+    classifier 'src'
 }
 
 [tasks.named('distZip'),
  tasks.named('srcDistZip'),
  tasks.named('dockerfileZip'),
- ]*.configure {
-  enabled = false
+]*.configure {
+    enabled = false
 }
 
 tasks.withType(Test) {
-  dependsOn installDist
-  environment 'GEODE_HOME', "$buildDir/install/${distributions.main.baseName}"
+    dependsOn installDist
+    environment 'GEODE_HOME', "$buildDir/install/${distributions.main.baseName}"
 }
 
 
@@ -655,43 +668,43 @@ upgradeTest.dependsOn ':geode-old-versions:build'
 
 /**Print the names of all jar files in a fileTree */
 def printJars(tree) {
-  tree.matching {include("**/*.jar")}.visit{ file ->
-    if(!file.isDirectory()) {
-      println file.name
+    tree.matching { include("**/*.jar") }.visit { file ->
+        if (!file.isDirectory()) {
+            println file.name
+        }
     }
-  }
 }
 
 task dumpInstalledJars(dependsOn: installDist) {
-  doLast {
-    description "Dump a list of all of the jars shipped with the binary distribution, for validation purposes"
-
-    FileTree installDir = fileTree(dir: installDist.destinationDir)
-
-    println("Jars in the binary install")
-    println("==========================")
-    printJars(installDir)
-
-    installDir.include("**/*.war").visit{ file ->
-      if(!file.isDirectory()) {
-          FileTree warContents = zipTree(file.file)
-          println ""
-          println file.name
-          println("==========================")
-          printJars(warContents)
-      }
+    doLast {
+        description "Dump a list of all of the jars shipped with the binary distribution, for validation purposes"
+
+        FileTree installDir = fileTree(dir: installDist.destinationDir)
+
+        println("Jars in the binary install")
+        println("==========================")
+        printJars(installDir)
+
+        installDir.include("**/*.war").visit { file ->
+            if (!file.isDirectory()) {
+                FileTree warContents = zipTree(file.file)
+                println ""
+                println file.name
+                println("==========================")
+                printJars(warContents)
+            }
+        }
     }
-  }
 }
 
 docker {
-  dependsOn(tasks.installDist)
-  name geodeDockerImageName
-  copySpec.from(tasks.installDist.outputs).into('geode')
+    dependsOn(tasks.installDist)
+    name geodeDockerImageName
+    copySpec.from(tasks.installDist.outputs).into('geode')
 }
 
 acceptanceTest {
-  dependsOn(tasks.docker)
+    dependsOn(tasks.docker)
 }
 
 apply from: Paths.get("${rootDir}", 'gradle', 'japicmp.gradle')
diff --git a/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/internal/cli/commands/StartServerCommandAcceptanceTest.java b/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/internal/cli/commands/StartServerCommandAcceptanceTest.java
index b955bf7..86eb694 100644
--- a/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/internal/cli/commands/StartServerCommandAcceptanceTest.java
+++ b/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/internal/cli/commands/StartServerCommandAcceptanceTest.java
@@ -32,6 +32,8 @@ import org.apache.geode.cache.server.CacheServer;
 import org.apache.geode.internal.AvailablePortHelper;
 import org.apache.geode.internal.cache.xmlcache.CacheCreation;
 import org.apache.geode.internal.cache.xmlcache.CacheXmlGenerator;
+import org.apache.geode.logging.internal.log4j.api.LogService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 import org.apache.geode.test.junit.rules.gfsh.GfshExecution;
 import org.apache.geode.test.junit.rules.gfsh.GfshRule;
 import org.apache.geode.test.junit.rules.gfsh.GfshScript;
@@ -58,7 +60,8 @@ public class StartServerCommandAcceptanceTest {
     File logFile = temporaryFolder.newFile(testName.getMethodName() + ".log");
     File cacheXmlFile = temporaryFolder.newFile(testName.getMethodName() + "Cache.xml");
 
-    CacheCreation creation = new CacheCreation();
+    CacheCreation creation = new CacheCreation(new ServiceLoaderModuleService(
+        LogService.getLogger()));
     CacheServer server = creation.addCacheServer();
     server.setPort(40404);
     server.setBindAddress(null);
diff --git a/geode-assembly/src/integrationTest/resources/assembly_content.txt b/geode-assembly/src/integrationTest/resources/assembly_content.txt
index cc2d508..d571bb0 100644
--- a/geode-assembly/src/integrationTest/resources/assembly_content.txt
+++ b/geode-assembly/src/integrationTest/resources/assembly_content.txt
@@ -733,6 +733,7 @@ javadoc/org/apache/geode/management/cli/CommandServiceException.html
 javadoc/org/apache/geode/management/cli/CommandStatement.html
 javadoc/org/apache/geode/management/cli/ConverterHint.html
 javadoc/org/apache/geode/management/cli/Disabled.html
+javadoc/org/apache/geode/management/cli/GeodeCommandMarker.html
 javadoc/org/apache/geode/management/cli/GfshCommand.html
 javadoc/org/apache/geode/management/cli/Result.Status.html
 javadoc/org/apache/geode/management/cli/Result.html
@@ -967,10 +968,18 @@ javadoc/org/apache/geode/security/package-frame.html
 javadoc/org/apache/geode/security/package-summary.html
 javadoc/org/apache/geode/security/package-tree.html
 javadoc/org/apache/geode/services/bootstrapping/BootstrappingService.html
+javadoc/org/apache/geode/services/bootstrapping/impl/BootstrappingServiceImpl.html
+javadoc/org/apache/geode/services/bootstrapping/impl/package-frame.html
+javadoc/org/apache/geode/services/bootstrapping/impl/package-summary.html
+javadoc/org/apache/geode/services/bootstrapping/impl/package-tree.html
 javadoc/org/apache/geode/services/bootstrapping/package-frame.html
 javadoc/org/apache/geode/services/bootstrapping/package-summary.html
 javadoc/org/apache/geode/services/bootstrapping/package-tree.html
 javadoc/org/apache/geode/services/management/ManagementService.html
+javadoc/org/apache/geode/services/management/impl/ManagementServiceImpl.html
+javadoc/org/apache/geode/services/management/impl/package-frame.html
+javadoc/org/apache/geode/services/management/impl/package-summary.html
+javadoc/org/apache/geode/services/management/impl/package-tree.html
 javadoc/org/apache/geode/services/management/package-frame.html
 javadoc/org/apache/geode/services/management/package-summary.html
 javadoc/org/apache/geode/services/management/package-tree.html
@@ -1027,12 +1036,15 @@ lib/geode-dependencies.jar
 lib/geode-gfsh-0.0.0.jar
 lib/geode-http-service-0.0.0.jar
 lib/geode-jca-0.0.0.rar
+lib/geode-launcher-0.0.0.jar
 lib/geode-log4j-0.0.0.jar
 lib/geode-logging-0.0.0.jar
 lib/geode-lucene-0.0.0.jar
 lib/geode-management-0.0.0.jar
 lib/geode-membership-0.0.0.jar
 lib/geode-memcached-0.0.0.jar
+lib/geode-module-bootstrapping-0.0.0.jar
+lib/geode-module-management-0.0.0.jar
 lib/geode-modules-0.0.0.jar
 lib/geode-old-client-support-0.0.0.jar
 lib/geode-protobuf-0.0.0.jar
diff --git a/geode-assembly/src/integrationTest/resources/dependency_classpath.txt b/geode-assembly/src/integrationTest/resources/dependency_classpath.txt
index 0ef68c7..0a48106 100644
--- a/geode-assembly/src/integrationTest/resources/dependency_classpath.txt
+++ b/geode-assembly/src/integrationTest/resources/dependency_classpath.txt
@@ -23,6 +23,9 @@ jackson-annotations-2.10.1.jar
 jackson-core-2.10.1.jar
 geode-membership-0.0.0.jar
 geode-http-service-0.0.0.jar
+geode-module-management-0.0.0.jar
+geode-module-bootstrapping-0.0.0.jar
+geode-launcher-0.0.0.jar
 geode-unsafe-0.0.0.jar
 antlr-2.7.7.jar
 rmiio-2.1.2.jar
diff --git a/geode-book/.gitignore b/geode-book/.gitignore
deleted file mode 100644
index 30545a4..0000000
--- a/geode-book/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-output/
-final_app/
diff --git a/geode-book/Gemfile b/geode-book/Gemfile
deleted file mode 100644
index ea05ef5..0000000
--- a/geode-book/Gemfile
+++ /dev/null
@@ -1,22 +0,0 @@
-# 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.
-
-source "https://rubygems.org"
-
-gem 'bookbindery', '10.1.14'
-
-gem 'libv8'
diff --git a/geode-book/Gemfile.lock b/geode-book/Gemfile.lock
deleted file mode 100644
index 9b60758..0000000
--- a/geode-book/Gemfile.lock
+++ /dev/null
@@ -1,207 +0,0 @@
-GEM
-  remote: https://rubygems.org/
-  specs:
-    activesupport (4.2.11.1)
-      i18n (~> 0.7)
-      minitest (~> 5.1)
-      thread_safe (~> 0.3, >= 0.3.4)
-      tzinfo (~> 1.1)
-    addressable (2.6.0)
-      public_suffix (>= 2.0.2, < 4.0)
-    ansi (1.5.0)
-    backports (3.15.0)
-    bookbindery (10.1.14)
-      ansi (~> 1.4)
-      css_parser
-      elasticsearch
-      fog-aws (~> 0.7.1)
-      font-awesome-sass (= 4.7.0)
-      git (~> 1.2.8)
-      middleman (= 4.1.10)
-      middleman-compass
-      middleman-livereload
-      middleman-sprockets
-      middleman-syntax (= 2.1.0)
-      nokogiri (= 1.8.2)
-      puma
-      rack-rewrite
-      redcarpet (~> 3.2.3)
-      rouge (!= 1.9.1)
-      therubyracer
-      thor (= 0.19.1)
-    builder (3.2.3)
-    chunky_png (1.3.11)
-    coffee-script (2.4.1)
-      coffee-script-source
-      execjs
-    coffee-script-source (1.12.2)
-    compass (1.0.3)
-      chunky_png (~> 1.2)
-      compass-core (~> 1.0.2)
-      compass-import-once (~> 1.0.5)
-      rb-fsevent (>= 0.9.3)
-      rb-inotify (>= 0.9)
-      sass (>= 3.3.13, < 3.5)
-    compass-core (1.0.3)
-      multi_json (~> 1.0)
-      sass (>= 3.3.0, < 3.5)
-    compass-import-once (1.0.5)
-      sass (>= 3.2, < 3.5)
-    concurrent-ruby (1.1.5)
-    contracts (0.13.0)
-    css_parser (1.7.0)
-      addressable
-    dotenv (2.7.5)
-    elasticsearch (7.3.0)
-      elasticsearch-api (= 7.3.0)
-      elasticsearch-transport (= 7.3.0)
-    elasticsearch-api (7.3.0)
-      multi_json
-    elasticsearch-transport (7.3.0)
-      faraday
-      multi_json
-    em-websocket (0.5.1)
-      eventmachine (>= 0.12.9)
-      http_parser.rb (~> 0.6.0)
-    erubis (2.7.0)
-    eventmachine (1.2.7)
-    excon (0.71.0)
-    execjs (2.7.0)
-    faraday (0.15.4)
-      multipart-post (>= 1.2, < 3)
-    fast_blank (1.0.0)
-    fastimage (2.1.5)
-    ffi (1.11.1)
-    fog-aws (0.7.6)
-      fog-core (~> 1.27)
-      fog-json (~> 1.0)
-      fog-xml (~> 0.1)
-      ipaddress (~> 0.8)
-    fog-core (1.45.0)
-      builder
-      excon (~> 0.58)
-      formatador (~> 0.2)
-    fog-json (1.2.0)
-      fog-core
-      multi_json (~> 1.10)
-    fog-xml (0.1.3)
-      fog-core
-      nokogiri (>= 1.5.11, < 2.0.0)
-    font-awesome-sass (4.7.0)
-      sass (>= 3.2)
-    formatador (0.2.5)
-    git (1.2.9.1)
-    haml (5.1.1)
-      temple (>= 0.8.0)
-      tilt
-    hamster (3.0.0)
-      concurrent-ruby (~> 1.0)
-    hashie (3.6.0)
-    http_parser.rb (0.6.0)
-    i18n (0.7.0)
-    ipaddress (0.8.3)
-    kramdown (1.17.0)
-    libv8 (3.16.14.19)
-    listen (3.0.8)
-      rb-fsevent (~> 0.9, >= 0.9.4)
-      rb-inotify (~> 0.9, >= 0.9.7)
-    memoist (0.16.0)
-    middleman (4.1.10)
-      coffee-script (~> 2.2)
-      compass-import-once (= 1.0.5)
-      haml (>= 4.0.5)
-      kramdown (~> 1.2)
-      middleman-cli (= 4.1.10)
-      middleman-core (= 4.1.10)
-      sass (>= 3.4.0, < 4.0)
-    middleman-cli (4.1.10)
-      thor (>= 0.17.0, < 2.0)
-    middleman-compass (4.0.1)
-      compass (>= 1.0.0, < 2.0.0)
-      middleman-core (>= 4.0.0)
-    middleman-core (4.1.10)
-      activesupport (~> 4.2)
-      addressable (~> 2.3)
-      backports (~> 3.6)
-      bundler (~> 1.1)
-      contracts (~> 0.13.0)
-      dotenv
-      erubis
-      execjs (~> 2.0)
-      fast_blank
-      fastimage (~> 2.0)
-      hamster (~> 3.0)
-      hashie (~> 3.4)
-      i18n (~> 0.7.0)
-      listen (~> 3.0.0)
-      memoist (~> 0.14)
-      padrino-helpers (~> 0.13.0)
-      parallel
-      rack (>= 1.4.5, < 2.0)
-      sass (>= 3.4)
-      servolux
-      tilt (~> 1.4.1)
-      uglifier (~> 3.0)
-    middleman-livereload (3.4.6)
-      em-websocket (~> 0.5.1)
-      middleman-core (>= 3.3)
-      rack-livereload (~> 0.3.15)
-    middleman-sprockets (4.1.1)
-      middleman-core (~> 4.0)
-      sprockets (>= 3.0)
-    middleman-syntax (2.1.0)
-      middleman-core (>= 3.2)
-      rouge (~> 1.0)
-    mini_portile2 (2.3.0)
-    minitest (5.11.3)
-    multi_json (1.13.1)
-    multipart-post (2.1.1)
-    nio4r (2.4.0)
-    nokogiri (1.8.2)
-      mini_portile2 (~> 2.3.0)
-    padrino-helpers (0.13.3.4)
-      i18n (~> 0.6, >= 0.6.7)
-      padrino-support (= 0.13.3.4)
-      tilt (>= 1.4.1, < 3)
-    padrino-support (0.13.3.4)
-      activesupport (>= 3.1)
-    parallel (1.17.0)
-    public_suffix (3.1.1)
-    puma (4.0.1)
-      nio4r (~> 2.0)
-    rack (1.6.11)
-    rack-livereload (0.3.17)
-      rack
-    rack-rewrite (1.5.1)
-    rb-fsevent (0.10.3)
-    rb-inotify (0.10.0)
-      ffi (~> 1.0)
-    redcarpet (3.2.3)
-    ref (2.0.0)
-    rouge (1.11.1)
-    sass (3.4.25)
-    servolux (0.13.0)
-    sprockets (3.7.2)
-      concurrent-ruby (~> 1.0)
-      rack (> 1, < 3)
-    temple (0.8.1)
-    therubyracer (0.12.3)
-      libv8 (~> 3.16.14.15)
-      ref
-    thor (0.19.1)
-    thread_safe (0.3.6)
-    tilt (1.4.1)
-    tzinfo (1.2.5)
-      thread_safe (~> 0.1)
-    uglifier (3.2.0)
-      execjs (>= 0.3.0, < 3)
-
-PLATFORMS
-  ruby
-
-DEPENDENCIES
-  bookbindery (= 10.1.14)
-  libv8
-
-BUNDLED WITH
-   1.17.3
diff --git a/geode-book/README.md b/geode-book/README.md
deleted file mode 100644
index c9d4dce..0000000
--- a/geode-book/README.md
+++ /dev/null
@@ -1,115 +0,0 @@
-# Apache Geode User Guide
-
-This document contains instructions for building and viewing the Apache Geode User Guide locally and moving the built guide to the Apache Geode website for publication.
-
-- [About](#about)
-- [Automatic build](#automatic-build)
-- [Manual build](#manual-build)
- - [Prerequisites](#prerequisites)
- - [Bookbinder Usage](#bookbinder-usage)
- - [Building the Documentation](#building-the-documentation)
-- [Publishing the User Guide to the Geode Website](#publishing-the-user-guide-to-the-geode-website)
-
-## About
-
-Apache Geode provides the full source for the Apache Geode User Guide in markdown format (see `{geode-project-dir}/geode-docs/CONTRIBUTE.md`). For every Apache Geode release the user guide is built and published to http://geode.apache.org/docs/. Users can build the markdown into an HTML user guide using [Bookbinder](https://github.com/pivotal-cf/bookbinder) and the instructions below.
-
-Bookbinder is a Ruby gem that binds  a unified documentation web application from markdown, html, and/or DITA source material. The source material for bookbinder must be stored either in local directories or in GitHub repositories. Bookbinder runs [Middleman](http://middlemanapp.com/) to produce a Rackup app that can be deployed locally or as a web application.
-
-## Automatic build
-
-Documentation can be built and previewed using the utility scripts at [dev-tools/docker/docs](https://github.com/apache/geode/tree/develop/dev-tools/docker/docs). These scripts use Docker, removing the requirement of installing Ruby and Bookbinder. They are based on the instructions described in the [Manual build](#manual-build) chapter.
-
-## Manual build
-
-### Prerequisites
-
-Bookbinder requires Ruby version 2.0.0-p195 or higher.
-
-Follow the instructions below to install Bookbinder:
-
-1. Add gem "bookbindery" to your Gemfile.
-2. Run `bundle install` to install the dependencies specified in your Gemfile.
-
-### Bookbinder Usage
-
-Bookbinder is meant to be used from within a project called a **book**. The book includes a configuration file that describes which documentation repositories to use as source materials. Bookbinder provides a set of scripts to aggregate those repositories and publish them to various locations.
-
-For Geode, a preconfigured **book** is provided in the directory `{geode-project-dir}/geode-book`, which gathers content from the directory `{geode-project-dir}/geode-docs`. You can use this configuration to build an HTML version of the Apache Geode User Guide on your local system.
-
-### Building the Documentation
-
-1. The GemFile in the `geode-book` directory already defines the `gem "bookbindery"` dependency. Make sure you are in the `{geode-project-dir}/geode-book` directory and enter:
-
-    ```
-    $ bundle install
-    ```
-
-   Note: You will not have to run `bundle install` on subsequent builds.
-
-2. To build the documentation locally using the installed `config.yml` file, enter:
-
-    ```
-    $ bundle exec bookbinder bind local
-    ```
-
-   Bookbinder converts the markdown source into HTML, which it puts in the `final_app` directory.
-
-3. Navigate to `{geode-project-dir}/geode-book/final_app/` and enter:
-
-    ```
-    $ bundle install
-    ```
-
-   Note: You will not have to run `bundle install` on subsequent builds. If you see errors during this step regarding the inability to install libv8, try running the command:
-    ```
-    $ gem install libv8 -v '3.16.14.15' --  --with-system-v8
-    ```
-   This can help you avoid errors with the default GCC compiler provided by Xcode on MacOS. This will only help circumvent the use of GCC to install libv8, so if you're on
-   an operating system where you do not have access to a system install of libv8 this may not be possible or necessary.
-
-
-4. To start a local website of the Apache Geode User Guide, enter:
-
-    ```
-    $ rackup
-    ```
-
-   You can now view the local documentation at <http://localhost:9292>.
-
-## Publishing the User Guide to the Geode Website
-
-Once you have reviewed your local build of the User Guide, you can publish it by copying it to the Apache Geode website. The target directory should contain a Geode version number.
-
-To copy the User Guide to the website repo:
-
-1. Create the destination directory by navigating to the geode-site repo. Check out the *master* branch and create a destination directory for the User Guide. The naming convention is:
-
-    ```
-{geode-site}/website/content/docs/guide/XY
-    ```
-where `XY` is the product version of your documentation (e.g., `{geode-site}/website/content/docs/guide/12` if you are publishing the documentation for Apache Geode 1.2).
-
-2. Navigate to the User Guide you have built in the Geode repository: `{geode-project-dir}/geode-book/final_app/public/docs/guide/XY`.
-
-3. Use `tar` to copy the directory in order to preserve links and other filesystem niceties.
-
-  a. Create the tarfile in your Desktop for easy access on the retrieval side.
-
-    ```
-    $ tar cvf ~/Desktop/new-guide-content.tar .
-    ```
-  b. Create the destination directory in the `geode-site` repo:
-
-    ```
-    $ mkdir -p {geode-site}/website/content/docs/guide/XY
-    ```
-
-  c. Navigate to the target directory and un-tar the userguide archive:
-
-    ```
-    $ cd {geode-site}/website/content/docs/guide/XY
-    $ tar xvf ~/Desktop/new-guide-content.tar
-    ```
-
-4. Follow the instructions in the README.md file on the *master* branch of the geode-site repo (`{geode-site}/README.md`) to build, review, and publish the Apache Geode website. You can also view the geode-site README.md file on [github: https://github.com/apache/geode-site](https://github.com/apache/geode-site).
diff --git a/geode-book/config.yml b/geode-book/config.yml
deleted file mode 100644
index 3c1c5d3..0000000
--- a/geode-book/config.yml
+++ /dev/null
@@ -1,48 +0,0 @@
-# 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.
-
-book_repo: apache/geode/geode-book
-public_host: localhost
-
-sections:
-- repository:
-    name: geode-docs
-  directory: docs/guide/114
-  subnav_template: geode-subnav
-
-template_variables:
-  product_name_long: Apache Geode
-  product_name: Geode
-  product_name_lowercase: geode
-  product_version: '1.14'
-  product_version_nodot: '114'
-  product_version_geode: '1.14'
-  min_java_version: '8'
-  min_java_update: '121'
-  support_url: http://geode.apache.org/community
-  product_url: http://geode.apache.org/
-  book_title: Apache Geode Documentation
-  support_link: <a href="http://geode.apache.org/community" target="_blank">Community</a>
-  support_call_to_action: <a href="http://geode.apache.org/community" target="_blank">Need Help?</a>
-  changelog_href: https://cwiki.apache.org/confluence/display/GEODE/Release+Notes
-  product_link: <div class="header-item"><a href="http://geode.apache.org/">Back to Geode Page</a></div>
-  domain_name: apache.org
-  book_title_short: Geode Docs
-  local_header_title: Apache Geode
-  local_header_img: /images/Apache_Geode_logo_symbol.png
-
-broken_link_exclusions: iefix|using_custom_classes|arrowhead|cppdocs|DotNetDocs
diff --git a/geode-book/master_middleman/source/archive_menus/_default.erb b/geode-book/master_middleman/source/archive_menus/_default.erb
deleted file mode 100644
index f728985..0000000
--- a/geode-book/master_middleman/source/archive_menus/_default.erb
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-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.
--->
-<div class="header-dropdown">
-  <a class="header-dropdown-link" >
-    <%= menu_title %>
-  </a>
-  <div class="header-dropdown-content">
-    <ul>
-      <% for link in dropdown_links %>
-        <li><a href="<%= link.values.first %>"><%= link.keys.first %></a></li>
-      <% end %>
-    </ul>
-  </div>
-</div>
diff --git a/geode-book/master_middleman/source/images/Apache_Geode_logo_symbol.png b/geode-book/master_middleman/source/images/Apache_Geode_logo_symbol.png
deleted file mode 100644
index 88f3996..0000000
Binary files a/geode-book/master_middleman/source/images/Apache_Geode_logo_symbol.png and /dev/null differ
diff --git a/geode-book/master_middleman/source/images/Apache_Geode_logo_symbol_white.png b/geode-book/master_middleman/source/images/Apache_Geode_logo_symbol_white.png
deleted file mode 100644
index 01d286c..0000000
Binary files a/geode-book/master_middleman/source/images/Apache_Geode_logo_symbol_white.png and /dev/null differ
diff --git a/geode-book/master_middleman/source/images/favicon.ico b/geode-book/master_middleman/source/images/favicon.ico
deleted file mode 100644
index 00aa630..0000000
Binary files a/geode-book/master_middleman/source/images/favicon.ico and /dev/null differ
diff --git a/geode-book/master_middleman/source/javascripts/book.js b/geode-book/master_middleman/source/javascripts/book.js
deleted file mode 100644
index 16edd95..0000000
--- a/geode-book/master_middleman/source/javascripts/book.js
+++ /dev/null
@@ -1,31 +0,0 @@
-//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.
-
-// Declare your book-specific javascript overrides in this file.
-//= require 'waypoints/waypoint'
-//= require 'waypoints/context'
-//= require 'waypoints/group'
-//= require 'waypoints/noframeworkAdapter'
-//= require 'waypoints/sticky'
-
-window.onload = function() {
-  Bookbinder.boot();
-  var sticky = new Waypoint.Sticky({
-    element: document.querySelector('#js-to-top'),
-    wrapper: '<div class="sticky-wrapper" />',
-    stuckClass: 'sticky',
-    offset: 100
-  });
-}
diff --git a/geode-book/master_middleman/source/javascripts/waypoints/context.js b/geode-book/master_middleman/source/javascripts/waypoints/context.js
deleted file mode 100644
index d005cb3..0000000
--- a/geode-book/master_middleman/source/javascripts/waypoints/context.js
+++ /dev/null
@@ -1,315 +0,0 @@
-//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.
-
-(function() {
-  'use strict'
-
-  function requestAnimationFrameShim(callback) {
-    window.setTimeout(callback, 1000 / 60)
-  }
-
-  var keyCounter = 0
-  var contexts = {}
-  var Waypoint = window.Waypoint
-  var oldWindowLoad = window.onload
-
-  /* http://imakewebthings.com/waypoints/api/context */
-  function Context(element) {
-    this.element = element
-    this.Adapter = Waypoint.Adapter
-    this.adapter = new this.Adapter(element)
-    this.key = 'waypoint-context-' + keyCounter
-    this.didScroll = false
-    this.didResize = false
-    this.oldScroll = {
-      x: this.adapter.scrollLeft(),
-      y: this.adapter.scrollTop()
-    }
-    this.waypoints = {
-      vertical: {},
-      horizontal: {}
-    }
-
-    element.waypointContextKey = this.key
-    contexts[element.waypointContextKey] = this
-    keyCounter += 1
-
-    this.createThrottledScrollHandler()
-    this.createThrottledResizeHandler()
-  }
-
-  /* Private */
-  Context.prototype.add = function(waypoint) {
-    var axis = waypoint.options.horizontal ? 'horizontal' : 'vertical'
-    this.waypoints[axis][waypoint.key] = waypoint
-    this.refresh()
-  }
-
-  /* Private */
-  Context.prototype.checkEmpty = function() {
-    var horizontalEmpty = this.Adapter.isEmptyObject(this.waypoints.horizontal)
-    var verticalEmpty = this.Adapter.isEmptyObject(this.waypoints.vertical)
-    if (horizontalEmpty && verticalEmpty) {
-      this.adapter.off('.waypoints')
-      delete contexts[this.key]
-    }
-  }
-
-  /* Private */
-  Context.prototype.createThrottledResizeHandler = function() {
-    var self = this
-
-    function resizeHandler() {
-      self.handleResize()
-      self.didResize = false
-    }
-
-    this.adapter.on('resize.waypoints', function() {
-      if (!self.didResize) {
-        self.didResize = true
-        Waypoint.requestAnimationFrame(resizeHandler)
-      }
-    })
-  }
-
-  /* Private */
-  Context.prototype.createThrottledScrollHandler = function() {
-    var self = this
-    function scrollHandler() {
-      self.handleScroll()
-      self.didScroll = false
-    }
-
-    this.adapter.on('scroll.waypoints', function() {
-      if (!self.didScroll || Waypoint.isTouch) {
-        self.didScroll = true
-        Waypoint.requestAnimationFrame(scrollHandler)
-      }
-    })
-  }
-
-  /* Private */
-  Context.prototype.handleResize = function() {
-    Waypoint.Context.refreshAll()
-  }
-
-  /* Private */
-  Context.prototype.handleScroll = function() {
-    var triggeredGroups = {}
-    var axes = {
-      horizontal: {
-        newScroll: this.adapter.scrollLeft(),
-        oldScroll: this.oldScroll.x,
-        forward: 'right',
-        backward: 'left'
-      },
-      vertical: {
-        newScroll: this.adapter.scrollTop(),
-        oldScroll: this.oldScroll.y,
-        forward: 'down',
-        backward: 'up'
-      }
-    }
-
-    for (var axisKey in axes) {
-      var axis = axes[axisKey]
-      var isForward = axis.newScroll > axis.oldScroll
-      var direction = isForward ? axis.forward : axis.backward
-
-      for (var waypointKey in this.waypoints[axisKey]) {
-        var waypoint = this.waypoints[axisKey][waypointKey]
-        var wasBeforeTriggerPoint = axis.oldScroll < waypoint.triggerPoint
-        var nowAfterTriggerPoint = axis.newScroll >= waypoint.triggerPoint
-        var crossedForward = wasBeforeTriggerPoint && nowAfterTriggerPoint
-        var crossedBackward = !wasBeforeTriggerPoint && !nowAfterTriggerPoint
-        if (crossedForward || crossedBackward) {
-          waypoint.queueTrigger(direction)
-          triggeredGroups[waypoint.group.id] = waypoint.group
-        }
-      }
-    }
-
-    for (var groupKey in triggeredGroups) {
-      triggeredGroups[groupKey].flushTriggers()
-    }
-
-    this.oldScroll = {
-      x: axes.horizontal.newScroll,
-      y: axes.vertical.newScroll
-    }
-  }
-
-  /* Private */
-  Context.prototype.innerHeight = function() {
-    /*eslint-disable eqeqeq */
-    if (this.element == this.element.window) {
-      return Waypoint.viewportHeight()
-    }
-    /*eslint-enable eqeqeq */
-    return this.adapter.innerHeight()
-  }
-
-  /* Private */
-  Context.prototype.remove = function(waypoint) {
-    delete this.waypoints[waypoint.axis][waypoint.key]
-    this.checkEmpty()
-  }
-
-  /* Private */
-  Context.prototype.innerWidth = function() {
-    /*eslint-disable eqeqeq */
-    if (this.element == this.element.window) {
-      return Waypoint.viewportWidth()
-    }
-    /*eslint-enable eqeqeq */
-    return this.adapter.innerWidth()
-  }
-
-  /* Public */
-  /* http://imakewebthings.com/waypoints/api/context-destroy */
-  Context.prototype.destroy = function() {
-    var allWaypoints = []
-    for (var axis in this.waypoints) {
-      for (var waypointKey in this.waypoints[axis]) {
-        allWaypoints.push(this.waypoints[axis][waypointKey])
-      }
-    }
-    for (var i = 0, end = allWaypoints.length; i < end; i++) {
-      allWaypoints[i].destroy()
-    }
-  }
-
-  /* Public */
-  /* http://imakewebthings.com/waypoints/api/context-refresh */
-  Context.prototype.refresh = function() {
-    /*eslint-disable eqeqeq */
-    var isWindow = this.element == this.element.window
-    /*eslint-enable eqeqeq */
-    var contextOffset = isWindow ? undefined : this.adapter.offset()
-    var triggeredGroups = {}
-    var axes
-
-    this.handleScroll()
-    axes = {
-      horizontal: {
-        contextOffset: isWindow ? 0 : contextOffset.left,
-        contextScroll: isWindow ? 0 : this.oldScroll.x,
-        contextDimension: this.innerWidth(),
-        oldScroll: this.oldScroll.x,
-        forward: 'right',
-        backward: 'left',
-        offsetProp: 'left'
-      },
-      vertical: {
-        contextOffset: isWindow ? 0 : contextOffset.top,
-        contextScroll: isWindow ? 0 : this.oldScroll.y,
-        contextDimension: this.innerHeight(),
-        oldScroll: this.oldScroll.y,
-        forward: 'down',
-        backward: 'up',
-        offsetProp: 'top'
-      }
-    }
-
-    for (var axisKey in axes) {
-      var axis = axes[axisKey]
-      for (var waypointKey in this.waypoints[axisKey]) {
-        var waypoint = this.waypoints[axisKey][waypointKey]
-        var adjustment = waypoint.options.offset
-        var oldTriggerPoint = waypoint.triggerPoint
-        var elementOffset = 0
-        var freshWaypoint = oldTriggerPoint == null
-        var contextModifier, wasBeforeScroll, nowAfterScroll
-        var triggeredBackward, triggeredForward
-
-        if (waypoint.element !== waypoint.element.window) {
-          elementOffset = waypoint.adapter.offset()[axis.offsetProp]
-        }
-
-        if (typeof adjustment === 'function') {
-          adjustment = adjustment.apply(waypoint)
-        }
-        else if (typeof adjustment === 'string') {
-          adjustment = parseFloat(adjustment)
-          if (waypoint.options.offset.indexOf('%') > - 1) {
-            adjustment = Math.ceil(axis.contextDimension * adjustment / 100)
-          }
-        }
-
-        contextModifier = axis.contextScroll - axis.contextOffset
-        waypoint.triggerPoint = elementOffset + contextModifier - adjustment
-        wasBeforeScroll = oldTriggerPoint < axis.oldScroll
-        nowAfterScroll = waypoint.triggerPoint >= axis.oldScroll
-        triggeredBackward = wasBeforeScroll && nowAfterScroll
-        triggeredForward = !wasBeforeScroll && !nowAfterScroll
-
-        if (!freshWaypoint && triggeredBackward) {
-          waypoint.queueTrigger(axis.backward)
-          triggeredGroups[waypoint.group.id] = waypoint.group
-        }
-        else if (!freshWaypoint && triggeredForward) {
-          waypoint.queueTrigger(axis.forward)
-          triggeredGroups[waypoint.group.id] = waypoint.group
-        }
-        else if (freshWaypoint && axis.oldScroll >= waypoint.triggerPoint) {
-          waypoint.queueTrigger(axis.forward)
-          triggeredGroups[waypoint.group.id] = waypoint.group
-        }
-      }
-    }
-
-    Waypoint.requestAnimationFrame(function() {
-      for (var groupKey in triggeredGroups) {
-        triggeredGroups[groupKey].flushTriggers()
-      }
-    })
-
-    return this
-  }
-
-  /* Private */
-  Context.findOrCreateByElement = function(element) {
-    return Context.findByElement(element) || new Context(element)
-  }
-
-  /* Private */
-  Context.refreshAll = function() {
-    for (var contextId in contexts) {
-      contexts[contextId].refresh()
-    }
-  }
-
-  /* Public */
-  /* http://imakewebthings.com/waypoints/api/context-find-by-element */
-  Context.findByElement = function(element) {
-    return contexts[element.waypointContextKey]
-  }
-
-  window.onload = function() {
-    if (oldWindowLoad) {
-      oldWindowLoad()
-    }
-    Context.refreshAll()
-  }
-
-  Waypoint.requestAnimationFrame = function(callback) {
-    var requestFn = window.requestAnimationFrame ||
-      window.mozRequestAnimationFrame ||
-      window.webkitRequestAnimationFrame ||
-      requestAnimationFrameShim
-    requestFn.call(window, callback)
-  }
-  Waypoint.Context = Context
-}())
diff --git a/geode-book/master_middleman/source/javascripts/waypoints/group.js b/geode-book/master_middleman/source/javascripts/waypoints/group.js
deleted file mode 100644
index 3f14d7c..0000000
--- a/geode-book/master_middleman/source/javascripts/waypoints/group.js
+++ /dev/null
@@ -1,120 +0,0 @@
-//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.
-
-(function() {
-  'use strict'
-
-  function byTriggerPoint(a, b) {
-    return a.triggerPoint - b.triggerPoint
-  }
-
-  function byReverseTriggerPoint(a, b) {
-    return b.triggerPoint - a.triggerPoint
-  }
-
-  var groups = {
-    vertical: {},
-    horizontal: {}
-  }
-  var Waypoint = window.Waypoint
-
-  /* http://imakewebthings.com/waypoints/api/group */
-  function Group(options) {
-    this.name = options.name
-    this.axis = options.axis
-    this.id = this.name + '-' + this.axis
-    this.waypoints = []
-    this.clearTriggerQueues()
-    groups[this.axis][this.name] = this
-  }
-
-  /* Private */
-  Group.prototype.add = function(waypoint) {
-    this.waypoints.push(waypoint)
-  }
-
-  /* Private */
-  Group.prototype.clearTriggerQueues = function() {
-    this.triggerQueues = {
-      up: [],
-      down: [],
-      left: [],
-      right: []
-    }
-  }
-
-  /* Private */
-  Group.prototype.flushTriggers = function() {
-    for (var direction in this.triggerQueues) {
-      var waypoints = this.triggerQueues[direction]
-      var reverse = direction === 'up' || direction === 'left'
-      waypoints.sort(reverse ? byReverseTriggerPoint : byTriggerPoint)
-      for (var i = 0, end = waypoints.length; i < end; i += 1) {
-        var waypoint = waypoints[i]
-        if (waypoint.options.continuous || i === waypoints.length - 1) {
-          waypoint.trigger([direction])
-        }
-      }
-    }
-    this.clearTriggerQueues()
-  }
-
-  /* Private */
-  Group.prototype.next = function(waypoint) {
-    this.waypoints.sort(byTriggerPoint)
-    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
-    var isLast = index === this.waypoints.length - 1
-    return isLast ? null : this.waypoints[index + 1]
-  }
-
-  /* Private */
-  Group.prototype.previous = function(waypoint) {
-    this.waypoints.sort(byTriggerPoint)
-    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
-    return index ? this.waypoints[index - 1] : null
-  }
-
-  /* Private */
-  Group.prototype.queueTrigger = function(waypoint, direction) {
-    this.triggerQueues[direction].push(waypoint)
-  }
-
-  /* Private */
-  Group.prototype.remove = function(waypoint) {
-    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
-    if (index > -1) {
-      this.waypoints.splice(index, 1)
-    }
-  }
-
-  /* Public */
-  /* http://imakewebthings.com/waypoints/api/first */
-  Group.prototype.first = function() {
-    return this.waypoints[0]
-  }
-
-  /* Public */
-  /* http://imakewebthings.com/waypoints/api/last */
-  Group.prototype.last = function() {
-    return this.waypoints[this.waypoints.length - 1]
-  }
-
-  /* Private */
-  Group.findOrCreate = function(options) {
-    return groups[options.axis][options.name] || new Group(options)
-  }
-
-  Waypoint.Group = Group
-}())
diff --git a/geode-book/master_middleman/source/javascripts/waypoints/noframeworkAdapter.js b/geode-book/master_middleman/source/javascripts/waypoints/noframeworkAdapter.js
deleted file mode 100644
index 4c55ca9..0000000
--- a/geode-book/master_middleman/source/javascripts/waypoints/noframeworkAdapter.js
+++ /dev/null
@@ -1,228 +0,0 @@
-//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.
-
-(function() {
-  'use strict'
-
-  var Waypoint = window.Waypoint
-
-  function isWindow(element) {
-    return element === element.window
-  }
-
-  function getWindow(element) {
-    if (isWindow(element)) {
-      return element
-    }
-    return element.defaultView
-  }
-
-  function classNameRegExp(className) {
-    return new RegExp("\\b" + className + "\\b");
-  }
-
-  function NoFrameworkAdapter(element) {
-    this.element = element
-    this.handlers = {}
-  }
-
-  NoFrameworkAdapter.prototype.innerHeight = function() {
-    var isWin = isWindow(this.element)
-    return isWin ? this.element.innerHeight : this.element.clientHeight
-  }
-
-  NoFrameworkAdapter.prototype.innerWidth = function() {
-    var isWin = isWindow(this.element)
-    return isWin ? this.element.innerWidth : this.element.clientWidth
-  }
-
-  NoFrameworkAdapter.prototype.off = function(event, handler) {
-    function removeListeners(element, listeners, handler) {
-      for (var i = 0, end = listeners.length - 1; i < end; i++) {
-        var listener = listeners[i]
-        if (!handler || handler === listener) {
-          element.removeEventListener(listener)
-        }
-      }
-    }
-
-    var eventParts = event.split('.')
-    var eventType = eventParts[0]
-    var namespace = eventParts[1]
-    var element = this.element
-
-    if (namespace && this.handlers[namespace] && eventType) {
-      removeListeners(element, this.handlers[namespace][eventType], handler)
-      this.handlers[namespace][eventType] = []
-    }
-    else if (eventType) {
-      for (var ns in this.handlers) {
-        removeListeners(element, this.handlers[ns][eventType] || [], handler)
-        this.handlers[ns][eventType] = []
-      }
-    }
-    else if (namespace && this.handlers[namespace]) {
-      for (var type in this.handlers[namespace]) {
-        removeListeners(element, this.handlers[namespace][type], handler)
-      }
-      this.handlers[namespace] = {}
-    }
-  }
-
-  /* Adapted from jQuery 1.x offset() */
-  NoFrameworkAdapter.prototype.offset = function() {
-    if (!this.element.ownerDocument) {
-      return null
-    }
-
-    var documentElement = this.element.ownerDocument.documentElement
-    var win = getWindow(this.element.ownerDocument)
-    var rect = {
-      top: 0,
-      left: 0
-    }
-
-    if (this.element.getBoundingClientRect) {
-      rect = this.element.getBoundingClientRect()
-    }
-
-    return {
-      top: rect.top + win.pageYOffset - documentElement.clientTop,
-      left: rect.left + win.pageXOffset - documentElement.clientLeft
-    }
-  }
-
-  NoFrameworkAdapter.prototype.on = function(event, handler) {
-    var eventParts = event.split('.')
-    var eventType = eventParts[0]
-    var namespace = eventParts[1] || '__default'
-    var nsHandlers = this.handlers[namespace] = this.handlers[namespace] || {}
-    var nsTypeList = nsHandlers[eventType] = nsHandlers[eventType] || []
-
-    nsTypeList.push(handler)
-    this.element.addEventListener(eventType, handler)
-  }
-
-  NoFrameworkAdapter.prototype.outerHeight = function(includeMargin) {
-    var height = this.innerHeight()
-    var computedStyle
-
-    if (includeMargin && !isWindow(this.element)) {
-      computedStyle = window.getComputedStyle(this.element)
-      height += parseInt(computedStyle.marginTop, 10)
-      height += parseInt(computedStyle.marginBottom, 10)
-    }
-
-    return height
-  }
-
-  NoFrameworkAdapter.prototype.outerWidth = function(includeMargin) {
-    var width = this.innerWidth()
-    var computedStyle
-
-    if (includeMargin && !isWindow(this.element)) {
-      computedStyle = window.getComputedStyle(this.element)
-      width += parseInt(computedStyle.marginLeft, 10)
-      width += parseInt(computedStyle.marginRight, 10)
-    }
-
-    return width
-  }
-
-  NoFrameworkAdapter.prototype.scrollLeft = function() {
-    var win = getWindow(this.element)
-    return win ? win.pageXOffset : this.element.scrollLeft
-  }
-
-  NoFrameworkAdapter.prototype.scrollTop = function() {
-    var win = getWindow(this.element)
-    return win ? win.pageYOffset : this.element.scrollTop
-  }
-
-  NoFrameworkAdapter.prototype.height = function(newHeight) {
-    this.element.style.height = newHeight;
-  }
-
-  NoFrameworkAdapter.prototype.removeClass = function(className) {
-    this.element.className = this.element.className.replace(classNameRegExp(className), '');
-  }
-
-  NoFrameworkAdapter.prototype.toggleClass = function(className, addClass) {
-    var check = classNameRegExp(className);
-    if (check.test(this.element.className)) {
-      if (!addClass) {
-        this.removeClass(className);
-      }
-    } else {
-      this.element.className += ' ' + className;
-    }
-  }
-
-  NoFrameworkAdapter.prototype.parent = function() {
-    return new NoFrameworkAdapter(this.element.parentNode);
-  }
-
-  NoFrameworkAdapter.prototype.wrap = function(wrapper) {
-    this.element.insertAdjacentHTML('beforebegin', wrapper)
-    var wrapperNode = this.element.previousSibling
-    this.element.parentNode.removeChild(this.element)
-    wrapperNode.appendChild(this.element)
-  }
-
-  NoFrameworkAdapter.extend = function() {
-    var args = Array.prototype.slice.call(arguments)
-
-    function merge(target, obj) {
-      if (typeof target === 'object' && typeof obj === 'object') {
-        for (var key in obj) {
-          if (obj.hasOwnProperty(key)) {
-            target[key] = obj[key]
-          }
-        }
-      }
-
-      return target
-    }
-
-    for (var i = 1, end = args.length; i < end; i++) {
-      merge(args[0], args[i])
-    }
-    return args[0]
-  }
-
-  NoFrameworkAdapter.inArray = function(element, array, i) {
-    return array == null ? -1 : array.indexOf(element, i)
-  }
-
-  NoFrameworkAdapter.isEmptyObject = function(obj) {
-    /* eslint no-unused-vars: 0 */
-    for (var name in obj) {
-      return false
-    }
-    return true
-  }
-
-  NoFrameworkAdapter.proxy = function(func, obj) {
-    return function() {
-      return func.apply(obj, arguments);
-    }
-  }
-
-  Waypoint.adapters.push({
-    name: 'noframework',
-    Adapter: NoFrameworkAdapter
-  })
-  Waypoint.Adapter = NoFrameworkAdapter
-}())
diff --git a/geode-book/master_middleman/source/javascripts/waypoints/sticky.js b/geode-book/master_middleman/source/javascripts/waypoints/sticky.js
deleted file mode 100644
index 371cac0..0000000
--- a/geode-book/master_middleman/source/javascripts/waypoints/sticky.js
+++ /dev/null
@@ -1,78 +0,0 @@
-//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.
-
-(function() {
-  'use strict'
-
-  var Waypoint = window.Waypoint;
-  var adapter = Waypoint.Adapter;
-
-  /* http://imakewebthings.com/waypoints/shortcuts/sticky-elements */
-  function Sticky(options) {
-    this.options = adapter.extend({}, Waypoint.defaults, Sticky.defaults, options)
-    this.element = this.options.element
-    this.$element = new adapter(this.element)
-    this.createWrapper()
-    this.createWaypoint()
-  }
-
-  /* Private */
-  Sticky.prototype.createWaypoint = function() {
-    var originalHandler = this.options.handler
-
-    this.waypoint = new Waypoint(adapter.extend({}, this.options, {
-      element: this.wrapper,
-      handler: adapter.proxy(function(direction) {
-        var shouldBeStuck = this.options.direction.indexOf(direction) > -1
-        var wrapperHeight = shouldBeStuck ? this.$element.outerHeight(true) : ''
-
-        this.$wrapper.height(wrapperHeight)
-        this.$element.toggleClass(this.options.stuckClass, shouldBeStuck)
-
-        if (originalHandler) {
-          originalHandler.call(this, direction)
-        }
-      }, this)
-    }))
-  }
-
-  /* Private */
-  Sticky.prototype.createWrapper = function() {
-    if (this.options.wrapper) {
-      this.$element.wrap(this.options.wrapper)
-    }
-    this.$wrapper = this.$element.parent()
-    this.wrapper = this.$wrapper.element
-  }
-
-  /* Public */
-  Sticky.prototype.destroy = function() {
-    if (this.$element.parent().element === this.wrapper) {
-      this.waypoint.destroy()
-      this.$element.removeClass(this.options.stuckClass)
-      if (this.options.wrapper) {
-        this.$element.unwrap()
-      }
-    }
-  }
-
-  Sticky.defaults = {
-    wrapper: '<div class="sticky-wrapper" />',
-    stuckClass: 'stuck',
-    direction: 'down right'
-  }
-
-  Waypoint.Sticky = Sticky
-}())
diff --git a/geode-book/master_middleman/source/javascripts/waypoints/waypoint.js b/geode-book/master_middleman/source/javascripts/waypoints/waypoint.js
deleted file mode 100644
index 0196b04..0000000
--- a/geode-book/master_middleman/source/javascripts/waypoints/waypoint.js
+++ /dev/null
@@ -1,175 +0,0 @@
-//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.
-
-(function() {
-  'use strict'
-
-  var keyCounter = 0
-  var allWaypoints = {}
-
-  /* http://imakewebthings.com/waypoints/api/waypoint */
-  function Waypoint(options) {
-    if (!options) {
-      throw new Error('No options passed to Waypoint constructor')
-    }
-    if (!options.element) {
-      throw new Error('No element option passed to Waypoint constructor')
-    }
-    if (!options.handler) {
-      throw new Error('No handler option passed to Waypoint constructor')
-    }
-
-    this.key = 'waypoint-' + keyCounter
-    this.options = Waypoint.Adapter.extend({}, Waypoint.defaults, options)
-    this.element = this.options.element
-    this.adapter = new Waypoint.Adapter(this.element)
-    this.callback = options.handler
-    this.axis = this.options.horizontal ? 'horizontal' : 'vertical'
-    this.enabled = this.options.enabled
-    this.triggerPoint = null
-    this.group = Waypoint.Group.findOrCreate({
-      name: this.options.group,
-      axis: this.axis
-    })
-    this.context = Waypoint.Context.findOrCreateByElement(this.options.context)
-
-    if (Waypoint.offsetAliases[this.options.offset]) {
-      this.options.offset = Waypoint.offsetAliases[this.options.offset]
-    }
-    this.group.add(this)
-    this.context.add(this)
-    allWaypoints[this.key] = this
-    keyCounter += 1
-  }
-
-  /* Private */
-  Waypoint.prototype.queueTrigger = function(direction) {
-    this.group.queueTrigger(this, direction)
-  }
-
-  /* Private */
-  Waypoint.prototype.trigger = function(args) {
-    if (!this.enabled) {
-      return
-    }
-    if (this.callback) {
-      this.callback.apply(this, args)
-    }
-  }
-
-  /* Public */
-  /* http://imakewebthings.com/waypoints/api/destroy */
-  Waypoint.prototype.destroy = function() {
-    this.context.remove(this)
-    this.group.remove(this)
-    delete allWaypoints[this.key]
-  }
-
-  /* Public */
-  /* http://imakewebthings.com/waypoints/api/disable */
-  Waypoint.prototype.disable = function() {
-    this.enabled = false
-    return this
-  }
-
-  /* Public */
-  /* http://imakewebthings.com/waypoints/api/enable */
-  Waypoint.prototype.enable = function() {
-    this.context.refresh()
-    this.enabled = true
-    return this
-  }
-
-  /* Public */
-  /* http://imakewebthings.com/waypoints/api/next */
-  Waypoint.prototype.next = function() {
-    return this.group.next(this)
-  }
-
-  /* Public */
-  /* http://imakewebthings.com/waypoints/api/previous */
-  Waypoint.prototype.previous = function() {
-    return this.group.previous(this)
-  }
-
-  /* Private */
-  Waypoint.invokeAll = function(method) {
-    var allWaypointsArray = []
-    for (var waypointKey in allWaypoints) {
-      allWaypointsArray.push(allWaypoints[waypointKey])
-    }
-    for (var i = 0, end = allWaypointsArray.length; i < end; i++) {
-      allWaypointsArray[i][method]()
-    }
-  }
-
-  /* Public */
-  /* http://imakewebthings.com/waypoints/api/destroy-all */
-  Waypoint.destroyAll = function() {
-    Waypoint.invokeAll('destroy')
-  }
-
-  /* Public */
-  /* http://imakewebthings.com/waypoints/api/disable-all */
-  Waypoint.disableAll = function() {
-    Waypoint.invokeAll('disable')
-  }
-
-  /* Public */
-  /* http://imakewebthings.com/waypoints/api/enable-all */
-  Waypoint.enableAll = function() {
-    Waypoint.invokeAll('enable')
-  }
-
-  /* Public */
-  /* http://imakewebthings.com/waypoints/api/refresh-all */
-  Waypoint.refreshAll = function() {
-    Waypoint.Context.refreshAll()
-  }
-
-  /* Public */
-  /* http://imakewebthings.com/waypoints/api/viewport-height */
-  Waypoint.viewportHeight = function() {
-    return window.innerHeight || document.documentElement.clientHeight
-  }
-
-  /* Public */
-  /* http://imakewebthings.com/waypoints/api/viewport-width */
-  Waypoint.viewportWidth = function() {
-    return document.documentElement.clientWidth
-  }
-
-  Waypoint.adapters = []
-
-  Waypoint.defaults = {
-    context: window,
-    continuous: true,
-    enabled: true,
-    group: 'default',
-    horizontal: false,
-    offset: 0
-  }
-
-  Waypoint.offsetAliases = {
-    'bottom-in-view': function() {
-      return this.context.innerHeight() - this.adapter.outerHeight()
-    },
-    'right-in-view': function() {
-      return this.context.innerWidth() - this.adapter.outerWidth()
-    }
-  }
-
-  window.Waypoint = Waypoint
-}())
diff --git a/geode-book/master_middleman/source/layouts/_book-footer.erb b/geode-book/master_middleman/source/layouts/_book-footer.erb
deleted file mode 100644
index c3b93f6..0000000
--- a/geode-book/master_middleman/source/layouts/_book-footer.erb
+++ /dev/null
@@ -1,23 +0,0 @@
-<!--
-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.
--->
-<div class="copyright">
-  <a href='/'>Apache Geode Documentation</a>
-  &copy; <%= Time.now.year %> <a href='http://www.apache.org/'>The Apache Software Foundation</a>.
-</div>
-<div class="support">
-  Need help? <a href="<%=vars.support_url%>" target="_blank">Visit the Community</a>
-</div>
diff --git a/geode-book/master_middleman/source/layouts/_local-header.erb b/geode-book/master_middleman/source/layouts/_local-header.erb
deleted file mode 100644
index 3c98674..0000000
--- a/geode-book/master_middleman/source/layouts/_local-header.erb
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-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.
--->
-<span style="font-weight:200;font-size:31px;" style="float:left;">
-  <% if vars.local_header_img %>
-    <img src="<%=vars.local_header_img%>" style="height:26px;">
-  <% end %>
-  <%= vars.local_header_title %>
-</span>
-<% if vars.changelog_href %>
-  <span class="local-header version-info" style="float:right;">
-    <a href="<%= vars.changelog_href %>">CHANGELOG</a>
-  </span>
-<% end %>
diff --git a/geode-book/master_middleman/source/layouts/_title.erb b/geode-book/master_middleman/source/layouts/_title.erb
deleted file mode 100644
index e9a0956..0000000
--- a/geode-book/master_middleman/source/layouts/_title.erb
+++ /dev/null
@@ -1,21 +0,0 @@
-<!--
-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.
--->
-<% if current_page.data.title %>
-  <h1 class="title-container" <%= current_page.data.dita ? 'style="display: none;"' : '' %>>
-    <%= current_page.data.title %>
-  </h1>
-<% end %>
diff --git a/geode-book/master_middleman/source/stylesheets/book-styles.scss b/geode-book/master_middleman/source/stylesheets/book-styles.scss
deleted file mode 100644
index a7ab274..0000000
--- a/geode-book/master_middleman/source/stylesheets/book-styles.scss
+++ /dev/null
@@ -1,18 +0,0 @@
-//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.
-
-* {
-  box-sizing: border-box;
-}
diff --git a/geode-book/master_middleman/source/stylesheets/partials/_book-base-values.scss b/geode-book/master_middleman/source/stylesheets/partials/_book-base-values.scss
deleted file mode 100644
index 93562f4..0000000
--- a/geode-book/master_middleman/source/stylesheets/partials/_book-base-values.scss
+++ /dev/null
@@ -1,14 +0,0 @@
-//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.
diff --git a/geode-book/master_middleman/source/stylesheets/partials/_book-vars.scss b/geode-book/master_middleman/source/stylesheets/partials/_book-vars.scss
deleted file mode 100644
index e2c5e3f..0000000
--- a/geode-book/master_middleman/source/stylesheets/partials/_book-vars.scss
+++ /dev/null
@@ -1,33 +0,0 @@
-//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.
-
-$navy: #243640;
-$blue1: #2185c5;
-$blue2: #a7cae1;
-$bluegray1: #4b6475;
-$teal1: #03786D;
-$teal2: #00a79d;
-
-$color-accent: $teal1;
-$color-accent-bright: $teal2;
-
-// link colors
-$color-link: $blue1;
-$color-link-border: $blue2;
-
-$color-border-tip: $blue2;
-
-$color-bg-header: $navy;
-$color-bg-dark: $bluegray1;
diff --git a/geode-book/master_middleman/source/subnavs/geode-subnav.erb b/geode-book/master_middleman/source/subnavs/geode-subnav.erb
deleted file mode 100644
index 0493253..0000000
--- a/geode-book/master_middleman/source/subnavs/geode-subnav.erb
+++ /dev/null
@@ -1,2518 +0,0 @@
-<!--
-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.
--->
-<div id="sub-nav" class="js-sidenav nav-container" role="navigation">
-    <a class="sidenav-title" data-behavior="SubMenuMobile">
-        Doc Index
-    </a>
-    <div class="nav-content">
-        <ul>
-            <li>
-                <a href="/docs/guide/<%=vars.product_version_nodot%>/about_geode.html">Apache Geode Documentation</a>
-            </li>
-            <li class="has_submenu">
-                <a href="/docs/guide/<%=vars.product_version_nodot%>/getting_started/book_intro.html">Getting Started with Apache Geode</a>
-                <ul>
-                    <li>
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/getting_started/geode_overview.html">About Apache Geode</a>
-                    </li>
-                    <li>
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/getting_started/product_intro.html">Main Features of Apache Geode</a>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/prereq_and_install.html">Prerequisites and Installation Instructions</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/getting_started/system_requirements/host_machine.html">Host Machine Requirements</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/getting_started/installation/install_standalone.html">How to Install</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/getting_started/setup_classpath.html">Setting Up the CLASSPATH</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/getting_started/uninstall_geode.html">How to Uninstall</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li>
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/getting_started/15_minute_quickstart_gfsh.html">Apache Geode in 15 Minutes or Less</a>
-                    </li>
-                </ul>
-            </li>
-            <li class="has_submenu">
-                <a href="/docs/guide/<%=vars.product_version_nodot%>/configuring/chapter_overview.html">Configuring and Running a Cluster</a>
-                <ul>
-                    <li>
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/configuring/cluster_config/gfsh_persist.html">Overview of the Cluster Configuration Service</a>
-                    </li>
-                    <li>
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/configuring/cluster_config/persisting_configurations.html">Tutorial—Creating and Using a Cluster Configuration</a>
-                    </li>
-                    <li>
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/configuring/cluster_config/deploying_application_jars.html">Deploying Application JARs to Apache Geode Members</a>
-                    </li>
-                    <li>
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/configuring/cluster_config/using_member_groups.html">Using Member Groups</a>
-                    </li>
-                    <li>
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/configuring/cluster_config/export-import.html">Exporting and Importing Cluster Configurations</a>
-                    </li>
-                    <li>
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/configuring/cluster_config/gfsh_config_troubleshooting.html">Cluster Configuration Files and Troubleshooting</a>
-                    </li>
-                    <li>
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/configuring/cluster_config/gfsh_remote.html">Using gfsh to Manage a Remote Cluster Over HTTP or HTTPS</a>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/configuring/running/deploying_config_files.html">Deploying Configuration Files without the Cluster Configuration Service</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/configuring/running/deploy_config_files_intro.html">Main Steps to Deploying Configuration Files</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/configuring/running/default_file_specs.html">Default File Specifications and Search Locations</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/configuring/running/change_file_spec.html">Changing the File Specifications</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/configuring/running/deploying_config_jar_files.html">Deploying Configuration Files in JAR Files</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li>
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/configuring/running/starting_up_shutting_down.html">Starting Up and Shutting Down Your System</a>
-                    </li>
-                    <li>
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/configuring/running/running_the_locator.html">Running Geode Locator Processes</a>
-                    </li>
-                    <li>
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/configuring/running/running_the_cacheserver.html">Running Geode Server Processes</a>
-                    </li>
-                    <li>
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/configuring/running/managing_output_files.html">Managing System Output Files</a>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/configuring/running/firewall_ports_config.html">Firewall Considerations</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/configuring/running/firewalls_connections.html">Firewalls and Connections</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/configuring/running/firewalls_ports.html">Firewalls and Ports</a>
-                            </li>
-                        </ul>
-                    </li>
-                <li>
-                    <a href="/docs/guide/<%=vars.product_version_nodot%>/configuring/running/cluster-management-service.html">Cluster Management Service (Experimental)</a>
-                </li>
-                </ul>
-            </li>
-            <li class="has_submenu">
-                <a href="/docs/guide/<%=vars.product_version_nodot%>/basic_config/book_intro.html">Basic Configuration and Programming</a>
-                <ul>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/basic_config/config_concepts/chapter_overview.html">
-                            Cluster and Cache Configuration</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/basic_config/config_concepts/distributed_system_member_configuration.html">Cluster Members</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/basic_config/gemfire_properties/setting_distributed_properties.html">Setting Properties</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/basic_config/the_cache/setting_cache_properties.html">Options for Configuring the Cache and Data Regions
-                                </a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/basic_config/config_concepts/local_vs_remote.html">Local and Remote Membership and Caching</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/basic_config/the_cache/chapter_overview.html">Cache Management</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/basic_config/the_cache/intro_cache_management.html">Introduction to Cache Management</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/basic_config/the_cache/managing_a_peer_server_cache.html">Managing a Peer or Server Cache</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/basic_config/the_cache/managing_a_client_cache.html">Managing a Client Cache</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/basic_config/the_cache/managing_a_secure_cache.html">Managing a Cache in a Secure System</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/basic_config/the_cache/managing_a_multiuser_cache.html">Managing RegionServices for Multiple Secure Users</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/basic_config/the_cache/setting_cache_initializer.html">Launching an Application after Initializing the Cache</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/basic_config/data_regions/chapter_overview.html">Data Regions</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/basic_config/data_regions/managing_data_regions.html">Region Management</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/basic_config/data_regions/region_naming.html">Region Naming</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/basic_config/data_regions/region_shortcuts.html">Region Shortcuts and Custom Named Region Attributes</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/basic_config/data_regions/store_retrieve_region_shortcuts.html">Storing and Retrieving Region Shortcuts and Custom Named Region Attributes</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/basic_config/data_regions/managing_region_attributes.html">Managing Region Attributes</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/basic_config/data_regions/creating_custom_attributes.html">Creating Custom Attributes for Regions and Entries</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/basic_config/data_regions/new_region_existing_data.html">Building a New Region with Existing Content</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/basic_config/data_entries_custom_classes/chapter_overview.html">
-                            Data Entries
-                        </a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/basic_config/data_entries_custom_classes/managing_data_entries.html">Managing Data Entries</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/basic_config/data_entries_custom_classes/using_custom_classes.html">Requirements for Using Custom Classes in Data Caching</a>
-                            </li>
-                        </ul>
-                    </li>
-                </ul>
-            </li>
-            <li class="has_submenu">
-                <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/book_intro.html">Topologies and Communication</a>
-                <ul>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/topology_concepts/chapter_overview.html">Topology and Communication General Concepts</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/topology_concepts/topology_types.html">Topology Types</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/topology_concepts/member_communication.html">Planning Topology and Communication
-                                </a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/topology_concepts/how_member_discovery_works.html">How Member Discovery Works</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/topology_concepts/how_communication_works.html">How Communication Works</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/topology_concepts/using_bind_addresses.html">Using Bind Addresses</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/topology_concepts/IPv4_and_IPv6.html">Choosing Between IPv4 and IPv6</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/p2p_configuration/chapter_overview.html">Peer-to-Peer Configuration</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/p2p_configuration/setting_up_a_p2p_system.html">Configuring Peer-to-Peer Discovery</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/p2p_configuration/setting_up_peer_communication.html">Configuring Peer Communication</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/p2p_configuration/configuring_peer_member_groups.html">Organizing Peers into Logical Member Groups</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/cs_configuration/chapter_overview.html">Client/Server Configuration</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/cs_configuration/standard_client_server_deployment.html">Standard Client/Server Deployment</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/topology_concepts/how_server_discovery_works.html">How Server Discovery Works</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/topology_concepts/how_the_pool_manages_connections.html">How Client/Server Connections Work</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/cs_configuration/setting_up_a_client_server_system.html">Configuring a Client/Server System</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/cs_configuration/configure_servers_into_logical_groups.html">Organizing Servers Into Logical Member Groups</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/cs_configuration/client_server_example_configurations.html">Client/Server Example Configurations</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/cs_configuration/client_server_whats_next.html">Fine-Tuning Your Client/Server Configuration</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/multi_site_configuration/chapter_overview.html">Multi-site (WAN) Configuration</a>
-                        <ul>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/topology_concepts/how_multisite_systems_work.html">How Multi-site (WAN) Systems Work</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/topology_concepts/multisite_overview.html#topic_70045702D3994BC692E75102CE01BD7C">
-                                            Overview of Multi-site Caching</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/topology_concepts/multisite_overview.html#topic_C74A0961937640B199396DC925D8D782">Consistency for WAN Updates</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/topology_concepts/multisite_overview.html#topic_1742957C8D4B4F7590847EB8DB6CD4F7">Discovery for Multi-Site Systems</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/topology_concepts/multisite_overview.html#topic_9AA37B43642D4DE19072CA3367C849BA">Gateway Senders</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/topology_concepts/multisite_overview.html#topic_4DB3D9CF01AD4F4899457D1250468D00">Gateway Receivers</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/multi_site_configuration/multisite_topologies.html">Multi-site (WAN) Topologies</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/topologies_and_comm/multi_site_configuration/setting_up_a_multisite_system.html">Configuring a Multi-site (WAN) System</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/events/filtering_multisite_events.html">Filtering Events for Multi-Site (WAN) Distribution</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/events/resolving_multisite_conflicts.html">Resolving Conflicting Events</a>
-                            </li>
-                        </ul>
-                    </li>
-                </ul>
-            </li>
-            <li class="has_submenu">
-                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/book_intro.html">Managing Apache Geode</a>
-                <ul>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/management/management_and_monitoring.html">Apache Geode Management and Monitoring</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/management/management_and_monitoring_features.html">Management and Monitoring Features</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/management/mm_overview.html">Overview of Geode Management and Monitoring Tools</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/management/management_system_overview.html">
-                                    Architecture and Components</a>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/management/jmx_manager_node.html">JMX Manager Operations</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/management/jmx_manager_operations.html">Starting a JMX Manager</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/management/jmx_manager_operations.html#topic_263072624B8D4CDBAD18B82E07AA44B6">Configuring a JMX Manager</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/management/jmx_manager_operations.html#topic_5B6DF783A14241399DC25C6EE8D0048A">Stopping a JMX Manager</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/management/mbean_architecture.html">Federated MBean Architecture</a>
-                                <ul>
-                                    <li class="has_submenu">
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/management/list_of_mbeans.html">List of Geode JMX MBeans</a>
-                                        <ul>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/management/list_of_mbeans_full.html">JMX Manager MBeans</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/management/list_of_mbeans_full.html#topic_48194A5BDF3F40F68E95A114DD702413">Managed Node MBeans</a>
-                                            </li>
-                                        </ul>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/management/mbeans_jconsole.html">Browsing Geode MBeans through JConsole</a>
-                                    </li>
-                                    <li class="has_submenu">
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/management/mbean_notifications.html">Geode JMX MBean Notifications</a>
-                                        <ul>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/management/notification_federation_and_alerts.html">Notification Federation</a>
-                                            </li>
-                                            <li class="has_submenu">
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/management/list_of_mbean_notifications.html">List of JMX MBean Notifications</a>
-                                                <ul>
-                                                    <li>
-                                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/management/list_of_mbean_notifications.html#reference_czt_hq2_vj">MemberMXBean Notifications</a>
-                                                    </li>
-                                                    <li>
-                                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/management/list_of_mbean_notifications.html#reference_dzt_hq2_vj">MemberMXBean Gateway Notifications</a>
-                                                    </li>
-                                                    <li>
-                                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/management/list_of_mbean_notifications.html#cacheservermxbean_notifications">CacheServerMXBean Notifications</a>
-                                                    </li>
-                                                    <li>
-                                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/management/list_of_mbean_notifications.html#distributedsystemmxbean_notifications">DistributedSystemMXBean Notifications</a>
-                                                    </li>
-                                                </ul>
-                                            </li>
-                                        </ul>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/management/configuring_rmi_connector.html">Configuring RMI Registry Ports and RMI Connectors</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/management/gfsh_and_management_api.html">Executing gfsh Commands through the Management API</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/heap_use/heap_and_off_heap_management.html">Managing Heap and Off-heap Memory</a>
-                        <ul>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/heap_use/heap_management.html">Managing Heap Memory</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/heap_use/heap_management.html#how_the_resource_manager_works">Using the Geode Resource Manager</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/heap_use/heap_management.html#how_the_resource_manager_works__section_EA5E52E65923486488A71E3E6F0DE9DA">How Background Eviction Is Performed</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/heap_use/heap_management.html#configuring_resource_manager_controlling_heap_use">Controlling Heap Use with the Resource Manager</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/heap_use/heap_management.html#configuring_resource_manager__section_4949882892DA46F6BB8588FA97037F45">Configure Geode for Heap LRU Management</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/heap_use/heap_management.html#tuning_jvm_gc_parameters">Tuning the JVM's Garbage Collection Parameters</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/heap_use/heap_management.html#configuring_resource_manager__section_DE1CC494C2B547B083AA00821250972A">Monitor and Tune Heap LRU Configurations</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/heap_use/heap_management.html#resource_manager_example_configurations">Resource Manager Example Configurations</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/heap_use/off_heap_management.html">Managing Off-Heap Memory</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/heap_use/lock_memory.html">Locking Memory (Linux Systems Only)</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/disk_storage/chapter_overview.html">Disk Storage</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/disk_storage/how_disk_stores_work.html">How Disk Stores Work</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/disk_storage/file_names_and_extensions.html">Disk Store File Names and Extensions</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/disk_storage/operation_logs.html">Disk Store Operation Logs</a>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/disk_storage/overview_using_disk_stores.html">Configuring Disk Stores</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/disk_storage/using_disk_stores.html">Designing and Configuring Disk Stores</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/disk_storage/disk_store_configuration_params.html">Disk Store Configuration Parameters</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/disk_storage/using_the_default_disk_store.html">Modifying the Default Disk Store</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/disk_storage/optimize_availability_and_performance.html">
-                                    Optimizing a System with Disk Stores</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/disk_storage/starting_system_with_disk_stores.html">Start Up and Shut Down with Disk Stores</a>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/disk_storage/managing_disk_stores.html">Disk Store Management</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/disk_storage/managing_disk_stores_cmds.html">Disk Store Management Commands and Operations</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/disk_storage/validating_disk_store.html">Validating a Disk Store</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/disk_storage/compacting_disk_stores.html">Running Compaction on Disk Store Log Files</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/disk_storage/keeping_offline_disk_store_in_sync.html">Keeping a Disk Store Synchronized with the Cache</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/disk_storage/disk_free_space_monitoring.html">Configuring Disk Free Space Monitoring
-                                        </a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/disk_storage/handling_missing_disk_stores.html">Handling Missing Disk Stores</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/disk_storage/managing_disk_buffer_flushes.html">Altering When Buffers Are Flushed to Disk</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/disk_storage/backup_restore_disk_store.html">Creating Backups for System Recovery and Operational Management</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/cache_snapshots/chapter_overview.html">Cache and Region Snapshots</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/cache_snapshots/using_cache_and_region_snapshots.html">Usage and Performance Notes</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/cache_snapshots/exporting_a_snapshot.html">Exporting Cache and Region Snapshots</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/cache_snapshots/importing_a_snapshot.html">Importing Cache and Region Snapshots</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/cache_snapshots/filtering_snapshot_entries.html">Filtering Entries During Import or Export</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/cache_snapshots/read_snapshots_programmatically.html">Reading Snapshots Programmatically</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/region_compression.html">Region Compression</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/region_compression.html#concept_a2c_rhc_gl">Guidelines on Using Compression</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/region_compression.html#topic_inm_whc_gl">How to Enable Compression in a Region</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/region_compression.html#topic_hqf_syj_g4">Working with Compressors
-                                </a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/region_compression.html#topic_omw_j3c_gl">Comparing Performance of Compressed and Non-Compressed Regions</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/network_partitioning/chapter_overview.html">Network Partitioning</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/network_partitioning/how_network_partitioning_management_works.html">How Network Partitioning Management Works</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/network_partitioning/failure_detection.html">Failure Detection and Membership Views</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/network_partitioning/membership_coordinators_lead_members_and_weighting.html">Membership Coordinators, Lead Members and Member Weighting</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/network_partitioning/network_partitioning_scenarios.html">Network Partitioning Scenarios</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/network_partitioning/handling_network_partitioning.html">Configure Apache Geode to Handle Network Partitioning</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/network_partitioning/preventing_network_partitions.html">Preventing Network Partitions</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/security/chapter_overview.html">Security</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/security/implementing_security.html">Security Implementation Introduction and Overview</a>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/security/security_audit_overview.html">Security Detail Considerations</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/security/security-audit.html">External Interfaces, Ports, and Services</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/security/security-audit.html#topic_263072624B8D4CDBAD18B82E07AA44B6">Resources That Must Be Protected</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/security/security-audit.html#topic_5B6DF783A14241399DC25C6EE8D0048A">Log File Locations</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/security/properties_file.html">Where to Place Security Configuration Settings</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/security/enable_security.html">Enable Security with Property Definitions</a>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/security/authentication_overview.html">Authentication</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/security/implementing_authentication.html">Implementing Authentication</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/security/authentication_examples.html">Authentication Example</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/security/authorization_overview.html">Authorization</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/security/implementing_authorization.html">Implementing Authorization</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/security/method_invocation_authorizers.html">Method Invocation Authorizers</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/security/authorization_example.html">Authorization Examples</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/security/post_processing.html">Post Processing of Region Data</a>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/security/ssl_overview.html">SSL</a>
-                                <ul>
-                                    <li class="has_submenu">
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/security/implementing_ssl.html">Configuring SSL</a>
-                                    <ul>
-                                        <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/security/implementing_ssl.html#ssl_configurable_components">SSL-Configurable Components</a>
-                                        </li>
-                                        <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/security/implementing_ssl.html#ssl_configuration_properties">SSL Configuration Properties</a>
-                                        </li>
-                                        <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/security/implementing_ssl.html#ssl_property_reference_tables">SSL Property Reference Tables</a>
-                                        </li>
-                                        <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/security/implementing_ssl.html#implementing_ssl__sec_ssl_impl_proc">Procedure</a>
-                                        </li>
-                                    </ul>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/security/ssl_example.html">SSL Sample Implementation</a>
-                                    </li>
-                                </ul>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/chapter_overview.html">Performance Tuning and Configuration</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/disabling_tcp_syn_cookies.html">Disabling TCP SYN Cookies</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/performance_on_vsphere.html">Improving Performance on vSphere</a>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/performance_controls.html">Performance Controls</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/performance_controls_data_serialization.html">Data Serialization</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/performance_controls_setting_cache_timeouts.html">Setting Cache Timeouts</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/performance_controls_controlling_socket_use.html">Controlling Socket Use</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/performance_controls_managing_slow_receivers.html">Management of Slow Receivers</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/performance_controls_increasing_cache_hits.html">Increasing the Ratio of Cache Hits</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/system_member_performance.html">System Member Performance</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/system_member_performance_distributed_system_member.html">Member Properties</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/system_member_performance_jvm_mem_settings.html">JVM Memory Settings and System Performance</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/system_member_performance_garbage.html">Garbage Collection and System Performance</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/system_member_performance_connection_thread_settings.html">Connection Thread Settings and Performance</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/slow_receivers.html">Slow Receivers with TCP/IP</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/slow_receivers_preventing_problems.html">Preventing Slow Receivers</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/slow_receivers_managing.html">Managing Slow Receivers</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/slow_messages.html">Slow distributed-ack Messages</a>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/socket_communication.html">Socket Communication</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/socket_communication_setting_socket_buffer_sizes.html">Setting Socket Buffer Sizes</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/socket_communication_ephemeral_tcp_port_limits.html">Ephemeral TCP Port Limits</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/socket_communication_have_enough_sockets.html">Making Sure You Have Enough Sockets</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/socket_tcp_keepalive.html">TCP/IP KeepAlive Configuration</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/socket_communication_tcpip_p2p_handshake_timeouts.html">TCP/IP Peer-to-Peer Handshake Timeouts</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/sockets_and_gateways.html">Configuring Sockets in Multi-Site (WAN) Deployments</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/udp_communication.html">UDP Communication</a>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/multicast_communication.html">Multicast Communication</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/multicast_communication_provisioning_bandwidth.html">Provisioning Bandwidth for Multicast</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/multicast_communication_testing_multicast_speed_limits.html">Testing Multicast Speed Limits</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/multicast_communication_configuring_speed_limits.html">Configuring Multicast Speed Limits</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/multicast_communication_runtime_considerations.html">Run-time Considerations for Multicast</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/multicast_communication_troubleshooting.html">Troubleshooting the Multicast Tuning Process</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/monitor_tune/cache_consistency.html">Maintaining Cache Consistency</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/logging/logging.html">Logging</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/logging/how_logging_works.html">How Geode Logging Works</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/logging/logging_categories.html">Understanding Log Messages and Their Categories</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/logging/logging_whats_next.html">Naming, Searching, and Creating Log Files</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/logging/setting_up_logging.html">Set Up Logging</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/logging/configuring_log4j2.html">Advanced Users—Configuring Log4j 2 for Geode</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/statistics/chapter_overview.html">Statistics</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/statistics/how_statistics_work.html">How Statistics Work</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/statistics/transient_region_and_entry_statistics.html">Transient Region and Entry Statistics</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/statistics/application_defined_statistics.html">Application-Defined and Custom Statistics</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/statistics/setting_up_statistics.html">Configuring and Using Statistics</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/statistics/viewing_statistics.html">Viewing Archived Statistics</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/troubleshooting/chapter_overview.html">Troubleshooting and System Recovery</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/troubleshooting/producing_troubleshooting_artifacts.html">Producing Artifacts for Troubleshooting</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/troubleshooting/diagnosing_system_probs.html">Diagnosing System Problems</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/troubleshooting/system_failure_and_recovery.html">System Failure and Recovery</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/member-reconnect.html">Handling Forced Cache Disconnection Using Autoreconnect</a>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/troubleshooting/recovering_from_app_crashes.html">Recovering from Application and Cache Server Crashes</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/troubleshooting/recovering_from_p2p_crashes.html">Recovering from Crashes with a Peer-to-Peer Configuration</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/troubleshooting/recovering_from_cs_crashes.html">Recovering from Crashes with a Client/Server Configuration</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/troubleshooting/recovering_from_machine_crashes.html">Recovering from Machine Crashes</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/troubleshooting/recovering_conflicting_data_exceptions.html">Recovering from ConfictingPersistentDataExceptions</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/troubleshooting/prevent_and_recover_disk_full_errors.html">Preventing and Recovering from Disk Full Errors</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/managing/troubleshooting/recovering_from_network_outages.html">Understanding and Recovering from Network Outages</a>
-                            </li>
-                        </ul>
-                    </li>
-                </ul>
-            </li>
-            <li class="has_submenu">
-                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/book_intro.html">Developing with Apache Geode</a>
-                <ul>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/region_options/chapter_overview.html">
-                            Region Data Storage and Distribution</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/region_options/storage_distribution_options.html">
-                                    Storage and Distribution Options</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/region_options/region_types.html">Region Types</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/region_options/data_hosts_and_accessors.html">Region Data Stores and Data Accessors</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/region_options/dynamic_region_creation.html">Creating Regions Dynamically</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/partitioned_regions/chapter_overview.html">Partitioned Regions</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/partitioned_regions/how_partitioning_works.html">Understanding Partitioning</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/partitioned_regions/managing_partitioned_regions.html">Configuring Partitioned Regions</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/partitioned_regions/configuring_bucket_for_pr.html">Configuring the Number of Buckets for a Partitioned Region</a>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/partitioned_regions/overview_custom_partitioning_and_data_colocation.html">Custom-Partitioning and Colocating Data</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/partitioned_regions/custom_partitioning_and_data_colocation.html">Understanding Custom Partitioning and Data Colocation</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/partitioned_regions/standard_custom_partitioning.html">Standard Custom Partitioning</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/partitioned_regions/fixed_custom_partitioning.html">Fixed Custom Partitioning</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/partitioned_regions/colocating_partitioned_region_data.html">Colocate Data from Different Partitioned Regions</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/partitioned_regions/overview_how_pr_ha_works.html">Configuring High Availability for Partitioned Regions</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/partitioned_regions/how_pr_ha_works.html">Understanding High Availability for Partitioned Regions</a>
-                                    </li>
-                                    <li class="has_submenu">
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/partitioned_regions/configuring_ha_for_pr.html">Configure High Availability for a Partitioned Region</a>
-                                        <ul>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/partitioned_regions/set_pr_redundancy.html">Set the Number of Redundant Copies</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/partitioned_regions/set_redundancy_zones.html">Configure Redundancy Zones for Members</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/partitioned_regions/set_enforce_unique_host.html">Set Enforce Unique Host</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/partitioned_regions/set_crash_redundancy_recovery.html">Configure Member Crash Redundancy Recovery for a Partitioned Region</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/partitioned_regions/set_join_redundancy_recovery.html">Configure Member Join Redundancy Recovery for a Partitioned Region</a>
-                                            </li>
-                                        </ul>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/partitioned_regions/overview_how_pr_single_hop_works.html">Configuring Single-Hop Client Access to Server-Partitioned Regions</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/partitioned_regions/how_pr_single_hop_works.html">Understanding Client Single-Hop Access to Server-Partitioned Regions</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/partitioned_regions/configure_pr_single_hop.html">Configure Client Single-Hop Access to Server-Partitioned Regions</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/partitioned_regions/rebalancing_pr_data.html">Rebalancing Partitioned Region Data</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/partitioned_regions/checking_region_redundancy.html">Checking Redundancy in Partitioned Regions</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/partitioned_regions/restoring_region_redundancy.html">Restoring Redundancy in Partitioned Regions</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/partitioned_regions/moving_partitioned_data.html">Moving Partitioned Region Data to Another Member</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/distributed_regions/chapter_overview.html">
-                            Distributed and Replicated Regions</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/distributed_regions/how_distribution_works.html">How Distribution Works</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/distributed_regions/choosing_level_of_dist.html">Options for Region Distribution</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/distributed_regions/how_replication_works.html">How Replication and Preloading Work</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/distributed_regions/managing_distributed_regions.html">Configure Distributed, Replicated, and Preloaded Regions</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/distributed_regions/locking_in_global_regions.html">Locking in Global Regions</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/distributed_regions/region_entry_versions.html">Consistency for Region Updates</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/distributed_regions/how_region_versioning_works.html#topic_7A4B6C6169BD4B1ABD356294F744D236">
-                                    Consistency Checking by Region Type</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/distributed_regions/how_region_versioning_works.html#topic_B64891585E7F4358A633C792F10FA23E">Configuring Consistency Checking</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/distributed_regions/how_region_versioning_works.html#topic_0BDACA590B2C4974AC9C450397FE70B2">Overhead for Consistency Checks</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/distributed_regions/how_region_versioning_works.html#topic_C5B74CCDD909403C815639339AA03758">How Consistency Checking Works for Replicated Regions</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/distributed_regions/how_region_versioning_works.html#topic_321B05044B6641FCAEFABBF5066BD399">How Destroy and Clear Operations Are Resolved</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/distributed_regions/how_region_versioning_works.html#topic_32ACFA5542C74F3583ECD30467F352B0">Transactions with Consistent Regions</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/general_region_data_management.html">General Region Data Management</a>
-                        <ul>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/storing_data_on_disk/chapter_overview.html">Persistence and Overflow</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/storing_data_on_disk/how_persist_overflow_work.html">How Persistence and Overflow Work</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/storing_data_on_disk/storing_data_on_disk.html">Configure Region Persistence and Overflow</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/storing_data_on_disk/overflow_config_examples.html">Overflow Configuration Examples</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/eviction/chapter_overview.html">Eviction</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/eviction/how_eviction_works.html">How Eviction Works</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/eviction/configuring_data_eviction.html">Configure Data Eviction</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/expiration/chapter_overview.html">Expiration</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/expiration/how_expiration_works.html">How Expiration Works</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/expiration/configuring_data_expiration.html">Configure Data Expiration</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/outside_data_sources/sync_outside_data.html">Keeping the Cache in Sync with Outside Data Sources</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/outside_data_sources/chapter_overview.html">Overview of Outside Data Sources</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/outside_data_sources/configuring_db_connections_using_JNDI.html">Configuring Database Connections Using JNDI</a>
-                                    </li>
-
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/outside_data_sources/how_data_loaders_work.html">How Data Loaders Work</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/outside_data_sources/implementing_data_loaders.html">Implement a Data Loader</a>
-                                    </li>
-                                </ul>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/data_serialization/chapter_overview.html">Data Serialization</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/data_serialization/data_serialization_options.html">Overview of Data Serialization</a>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/data_serialization/gemfire_pdx_serialization.html">Geode PDX Serialization</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/data_serialization/PDX_Serialization_Features.html">Geode PDX Serialization Features</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/data_serialization/use_pdx_high_level_steps.html">High Level Steps for Using PDX Serialization
-                                        </a>
-                                    </li>
-                                    <li class="has_submenu">
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/data_serialization/auto_serialization.html">Using Automatic Reflection-Based PDX Serialization</a>
-                                        <ul>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/data_serialization/autoserialization_with_class_pattern_strings.html">Customizing Serialization with Class Pattern Strings</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/data_serialization/extending_the_autoserializer.html">Extending the ReflectionBasedAutoSerializer</a>
-                                            </li>
-                                        </ul>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/data_serialization/use_pdx_serializer.html">Serializing Your Domain Object with a PdxSerializer</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/data_serialization/use_pdx_serializable.html">Implementing PdxSerializable in Your Domain Object</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/data_serialization/program_application_for_pdx.html">Programming Your Application to Use PdxInstances</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/data_serialization/jsonformatter_pdxinstances.html">Adding JSON Documents to the Geode Cache</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/data_serialization/using_PdxInstanceFactory.html">Using PdxInstanceFactory to Create PdxInstances</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/data_serialization/persist_pdx_metadata_to_disk.html">Persisting PDX Metadata to Disk</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/data_serialization/using_pdx_region_entry_keys.html">Using PDX Objects as Region Entry Keys</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/data_serialization/gemfire_data_serialization.html">Geode Data Serialization (DataSerializable and DataSerializer)</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/data_serialization/java_serialization.html">Standard Java Serialization</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/events/chapter_overview.html">Events and Event Handling</a>
-                        <ul>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/events/how_events_work.html">How Events Work</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/events/how_cache_events_work.html">Peer-to-Peer Event Distribution</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/events/how_client_server_distribution_works.html">Client-to-Server Event Distribution</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/events/how_multisite_distribution_works.html">
-                                            Multi-Site (WAN) Event Distribution</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/events/list_of_event_handlers_and_events.html">List of Event Handlers and Events</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/events/event_handler_overview.html">Implementing Geode Event Handlers</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/events/implementing_cache_event_handlers.html">Implementing Cache Event Handlers</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/events/implementing_write_behind_event_handler.html">Implementing an AsyncEventListener for Write-Behind Cache Event Handling</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/events/writing_callbacks_that_modify_the_cache.html">How to Safely Modify the Cache from an Event Handler Callback</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/events/cache_event_handler_examples.html">Cache Event Handler Examples</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/events/configure_p2p_event_messaging.html">Configuring Peer-to-Peer Event Messaging</a>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/events/configure_client_server_event_messaging.html">Configuring Client/Server Event Messaging
-                                </a>
-                                <ul>
-                                    <li class="has_submenu">
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/events/configuring_highly_available_servers.html">Configuring Highly Available Servers</a>
-                                        <ul>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/events/ha_event_messaging_whats_next.html">Highly Available Client/Server Event Messaging</a>
-                                            </li>
-                                        </ul>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/events/implementing_durable_client_server_messaging.html">Implementing Durable Client/Server Messaging</a>
-                                    </li>
-                                    <li class="has_submenu">
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/events/tune_client_server_event_messaging.html">Tuning Client/Server Event Messaging</a>
-                                        <ul>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/events/conflate_server_subscription_queue.html">Conflate the Server Subscription Queue</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/events/limit_server_subscription_queue_size.html">Limit the Server's Subscription Queue Memory Use
-                                                </a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/events/tune_client_message_tracking_timeout.html">Tune the Client's Subscription Message Tracking Timeout</a>
-                                            </li>
-                                        </ul>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/events/configure_multisite_event_messaging.html">Configuring Multi-Site (WAN) Event Queues</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/events/configuring_highly_available_gateway_queues.html">Persisting an Event Queue</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/events/configuring_gateway_concurrency_levels.html">Configuring Dispatcher Threads and Order Policy for Event Distribution</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/events/conflate_multisite_gateway_queue.html">Conflating Events in a Queue</a>
-                                    </li>
-                                </ul>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/delta_propagation/chapter_overview.html">
-                            Delta Propagation</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/delta_propagation/how_delta_propagation_works.html">How Delta Propagation Works</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/delta_propagation/when_to_use_delta_prop.html">When to Avoid Delta Propagation</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/delta_propagation/delta_propagation_properties.html">Delta Propagation Properties</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/delta_propagation/implementing_delta_propagation.html">Implementing Delta Propagation</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/delta_propagation/errors_in_delta_propagation.html">Errors In Delta Propagation</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/delta_propagation/delta_propagation_example.html">Delta Propagation Example</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/querying_basics/chapter_overview.html">Querying</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/getting_started/querying_quick_reference.html">Querying FAQ and Examples</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/querying_basics/query_basics.html">Querying with OQL</a>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/querying_basics/running_a_query.html">Writing and Executing a Query in OQL</a>
-                                <ul>
-                                    <li class="has_submenu">
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/querying_basics/what_is_a_query_string.html">Building a Query String</a>
-                                        <ul>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_select/the_import_statement.html">IMPORT Statement</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_select/the_from_clause.html">FROM Clause</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_select/the_where_clause.html">WHERE Clause</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_select/the_select_statement.html">SELECT Statement</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_select/aggregates.html">OQL Aggregate Functions</a>
-                                            </li>
-                                        </ul>
-                                    </li>
-                                    <li class="has_submenu">
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_additional/query_language_features.html">OQL Syntax and Semantics</a>
-                                        <ul>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/querying_basics/supported_character_sets.html">Supported Character Sets</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_additional/supported_keywords.html">Supported Keywords</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_additional/case_sensitivity.html">Case Sensitivity</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/querying_basics/comments_in_query_strings.html">Comments in Query Strings</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/querying_basics/query_grammar_and_reserved_words.html">Query Language Grammar</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_additional/operators.html">Operators</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/querying_basics/reserved_words.html">Reserved Words</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_additional/literals.html">Supported Literals</a>
-                                            </li>
-                                        </ul>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/querying_basics/restrictions_and_unsupported_features.html">Query Language Restrictions and Unsupported Features</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_additional/advanced_querying.html">Advanced Querying</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/querying_basics/performance_considerations.html">Performance Considerations</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/querying_basics/monitor_queries_for_low_memory.html">Monitoring Low Memory When Querying</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_additional/query_timeout.html">Timeouts for Long-Running Queries</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_additional/using_query_bind_parameters.html">Using Query Bind Parameters</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_additional/querying-a-specific-member.html">Querying a Specific Member</a>
-                                    </li>
-                                    <li class="has_submenu">
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/querying_basics/querying_partitioned_regions.html">
-                                            Querying Partitioned Regions</a>
-                                        <ul>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_additional/order_by_on_partitioned_regions.html">Using ORDER BY on Partitioned Regions</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_additional/query_on_a_single_node.html">Querying a Partitioned Region on a Single Node</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_additional/partitioned_region_key_or_field_value.html">Optimizing Queries on Data Partitioned by a Key or Field Value</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/partitioned_regions/join_query_partitioned_regions.html">Performing an Equi-Join Query on Partitioned Regions</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_additional/partitioned_region_query_restrictions.html">Partitioned Region Query Restrictions</a>
-                                            </li>
-                                        </ul>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_additional/query_debugging.html">Query Debugging</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_index/query_index.html">Working with Indexes</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_index/indexing_guidelines.html">Tips and Guidelines on Using Indexes</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_index/creating_an_index.html">Creating, Listing and Removing Indexes</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_index/creating_key_indexes.html">Creating Key Indexes</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_index/creating_hash_indexes.html">Creating Hash Indexes</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_index/creating_map_indexes.html">Creating Indexes on Map Fields ("Map Indexes")</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_index/create_multiple_indexes.html">Creating Multiple Indexes at Once</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_index/maintaining_indexes.html">Maintaining Indexes (Synchronously or Asynchronously) and Index Storage</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_index/query_index_hints.html">Using Query Index Hints</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_index/indexes_on_single_region_queries.html">Using Indexes on Single Region Queries</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_index/using_indexes_with_equijoin_queries.html">Using Indexes with Equi-Join Queries</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_index/indexes_with_overflow_regions.html">Using Indexes with Overflow Regions</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_index/using_indexes_with_equijoin_queries_multiple_regions.html">Using Indexes on Equi-Join Queries using Multiple Regions</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/query_index/index_samples.html">Index Samples</a>
-                                    </li>
-                                </ul>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/continuous_querying/chapter_overview.html">
-                            Continuous Querying</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/continuous_querying/how_continuous_querying_works.html">How Continuous Querying Works</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/continuous_querying/implementing_continuous_querying.html">Implementing Continuous Querying</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/continuous_querying/continuous_querying_whats_next.html">Managing Continuous Querying</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/transactions/chapter_overview.html">Transactions</a>
-                        <ul>
-                           <li>
-                           <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/transactions/transactions_intro.html">Adherence to ACID Promises</a>
-                           </li>
-                           <li>
-                           <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/transactions/directed_example.html">Code Examples</a>
-                           </li>
-                           <li>
-                           <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/transactions/design_considerations.html">Design Considerations</a>
-                           </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/function_exec/chapter_overview.html">Function Execution</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/function_exec/how_function_execution_works.html">How Function Execution Works</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/developing/function_exec/function_execution.html">Executing a Function in Apache Geode</a>
-                            </li>
-                        </ul>
-                    </li>
-                </ul>
-            </li>
-            <li class="has_submenu">
-                <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/book_intro.html">Developing REST Applications for Apache Geode</a>
-                <ul>
-                    <li>
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/chapter_overview.html">Geode REST API Overview</a>
-                    </li>
-                    <li>
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/rest_prereqs.html">Prerequisites and Limitations for Writing REST Applications</a>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/setup_config.html">Setup and Configuration</a>
-                        <ul>
-                        <li><a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/setup_config.html#setup_config_enabling_rest">Enabling the REST API</a></li>
-                        <li><a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/setup_config.html#setup_config_starting_rest">Starting the REST API Service</a></li>
-                        <li><a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/setup_config.html#setup_config_implementing_auth">Implementing Authentication</a></li>
-                        <li><a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/setup_config.html#setup_config_implementing_auth">Programmatic Startup</a></li>
-                        </ul>
-                    </li>
-                    <li>
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/using_swagger.html">Using the Swagger UI to Browse REST APIs</a>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/develop_rest_apps.html">Developing REST Applications</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/develop_rest_apps.html#topic_qhs_f25_m4">Working with Regions</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/develop_rest_apps.html#topic_fcn_g25_m4">Working with Queries</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/develop_rest_apps.html#topic_rbc_h25_m4">Working with Functions</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li>
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/rest_examples.html">Sample REST Applications</a>
-                    </li>
-                    <li>
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/troubleshooting.html">Troubleshooting and FAQ</a>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/rest_api_reference.html">Apache Geode REST API Reference</a>
-                        <ul>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/rest_regions.html">Region Endpoints</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/get_regions.html">GET /geode/v1</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/get_region_data.html">GET /geode/v1/{region}</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/get_region_keys.html">GET /geode/v1/{region}/keys</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/get_region_key_data.html">GET /geode/v1/{region}/{key}</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/get_region_data_for_multiple_keys.html">GET /geode/v1/{region}/{key1},{key2},...,{keyN}</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/head_region_size.html">HEAD /geode/v1/{region}</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/post_if_absent_data.html">POST /geode/v1/{region}?key=&lt;key&gt;</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/put_update_data.html">PUT /geode/v1/{region}/{key}</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/put_multiple_values_for_keys.html">PUT /geode/v1/{region}/{key1},{key2},...{keyN}</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/put_replace_data.html">PUT /geode/v1/{region}/{key}?op=REPLACE</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/put_update_cas_data.html">PUT /geode/v1/{region}/{key}?op=CAS</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/delete_all_data.html">DELETE /geode/v1/{region}</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/delete_data_for_key.html">DELETE /geode/v1/{region}/{key}</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/delete_data_for_multiple_keys.html">DELETE /geode/v1/{region}/{key1},{key2},...{keyN}</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/rest_queries.html">Query Endpoints</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/get_queries.html">GET /geode/v1/queries</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/post_create_query.html">POST /geode/v1/queries?id=&lt;queryId&gt;&amp;q=&lt;OQL-statement&gt;</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/post_execute_query.html">POST /geode/v1/queries/{queryId}</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/put_update_query.html">PUT /geode/v1/queries/{queryId}</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/delete_named_query.html">DELETE /geode/v1/queries/{queryId}</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/get_execute_adhoc_query.html">GET /geode/v1/queries/adhoc?q=&lt;OQL-statement&gt;</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/rest_functions.html">Function Endpoints</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/get_functions.html">GET /geode/v1/functions</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/post_execute_functions.html">POST /geode/v1/functions/{functionId}</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/rest_admin.html">Administrative Endpoints</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/ping_service.html">[HEAD | GET] /geode/v1/ping</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/rest_apps/get_servers.html">GET /geode/v1/servers</a>
-                                    </li>
-                                </ul>
-                            </li>
-                        </ul>
-                    </li>
-                </ul>
-            </li>
-            <li class="has_submenu">
-                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/book_intro.html">Tools and Modules</a>
-                <ul>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/chapter_overview.html">
-gfsh</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/about_gfsh.html">What You Can Do with gfsh</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/starting_gfsh.html">Starting gfsh</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/configuring_gfsh.html">Configuring the gfsh Environment</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/useful_gfsh_shell_variables.html">Useful gfsh Shell Variables</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/getting_started_gfsh.html">Basic Shell Features and Command-Line Usage</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/json_in_gfsh.html">Specifying JSON within Command-Line Options</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/tour_of_gfsh.html">Tutorial—Performing Common Tasks with gfsh</a>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/gfsh_quick_reference.html">Quick Reference of gfsh Commands by Functional Area</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/quick_ref_commands_by_area.html#topic_77DA6E3929404EB4AC24230CC7C21493">Basic Geode gfsh Commands</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/quick_ref_commands_by_area.html#topic_EB854534301A477BB01058B3B142AE1D">Configuration Commands</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/quick_ref_commands_by_area.html#topic_C7DB8A800D6244AE8FF3ADDCF139DCE4">Data Commands</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/quick_ref_commands_by_area.html#topic_1B47A0E120124EB6BF08A467EB510412">Deployment Commands</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/quick_ref_commands_by_area.html#topic_1ACC91B493EE446E89EC7DBFBBAE00EA">Disk Store Commands</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/quick_ref_commands_by_area.html#topic_10613D4850F04A3EB507F6B441AD3413">Durable CQ and Client Commands</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/quick_ref_commands_by_area.html#topic_8BB061D1A7A9488C819FE2B7881A1278">Function Execution Commands</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/quick_ref_commands_by_area.html#topic_F0AE5CE40D6D49BF92247F5EF4F871D2">Gateway (WAN) Commands</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/quick_ref_commands_by_area.html#topic_B742E9E862BA457082E2346581C97D03">Geode Monitoring Commands</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/quick_ref_commands_by_area.html#topic_688C66526B4649AFA51C0F72F34FA45E">Index Commands</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/quick_ref_commands_by_area.html#topic_2A6DA4078E4E496A9F725A29BC4CFD0D">JMX Connection Commands</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/quick_ref_commands_by_area.html#topic_1C82E6F1B2AF4A65A8DA6B3C846BAC13">Locator Commands</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/quick_ref_commands_by_area.html#topic_lucene_commands">Lucene Commands</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/quick_ref_commands_by_area.html#topic_cvg_bls_5q">PDX Commands</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/quick_ref_commands_by_area.html#topic_EF03129A40EE492984F3B6248596E1DD">Region Commands</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/quick_ref_commands_by_area.html#topic_8A341FF86958466E9E64CF06CD21FED9">Server Commands</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/gfsh_command_index.html">gfsh Command Help</a>
-                                <ul>
-                                    <li class="has_submenu">
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/alter.html">alter</a>
-                                        <ul>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/alter.html#topic_alter_async_event_queue">alter async-event-queue</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/alter.html#topic_99BCAD98BDB5470189662D2F308B68EB">alter disk-store</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/alter.html#topic_alter_query_service">alter query-service</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/alter.html#topic_E74ED23CB60342538B2175C326E7D758">alter region</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/alter.html#topic_7E6B7E1B972D4F418CB45354D1089C2B">alter runtime</a>
-                                            </li>
-                                        </ul>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/backup.html">backup disk-store</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/change.html">change loglevel</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/clear.html">clear defined indexes</a>
-                                    </li>
-                                    <li class="has_submenu">
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/close.html">close</a>
-                                        <ul>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/close.html#topic_4125AAAB9FE44CD787166E48B694C41D">close durable-client</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/close.html#topic_1BC15B3132BA480DB227921A9B3ABDD1">close durable-cq</a>
-                                            </li>
-                                        </ul>
-                                    </li>
-                                    <li class="has_submenu">
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/compact.html">compact</a>
-                                        <ul>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/compact.html#topic_F123C95C076F424E9AA8AC4F1F6324CC">compact disk-store</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/compact.html#topic_9CCFCB2FA2154E16BD775439C8ABC8FB">compact offline-disk-store</a>
-                                            </li>
-                                        </ul>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/configure.html">configure</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/connect.html">connect</a>
-                                    </li>
-                                    <li class="has_submenu">
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/create.html">create</a>
-                                        <ul>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/create.html#topic_ryz_pb1_dk">create async-event-queue</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/create.html#topic_w2t_l3m_qq">create defined indexes</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/create.html#topic_bkn_zty_ck">create disk-store</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/create.html#topic_a4x_pb1_dk">create gateway-receiver</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/create.html#topic_hg2_bjz_ck">create gateway-sender</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/create.html#topic_960A5B6FD3D84E1881EE128E299DD12D">create index</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/create.html#create_jndi-binding">create jndi-binding</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/create.html#create_lucene_index">create lucene index</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/create.html#topic_54B0985FEC5241CA9D26B0CE0A5EA863">create region</a>
-                                            </li>
-                                        </ul>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/debug.html">debug</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/define.html">define index</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/deploy.html">deploy</a>
-                                    </li>
-                                    <li class="has_submenu">
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/describe.html">describe</a>
-                                        <ul>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/describe.html#topic_gyr_jgz_ck">describe client</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/describe.html#topic_3C2C817D999C4E40AF788808B7B6AF99">describe config</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/describe.html#topic_591DC6B781B641268E6173E69AC6D201">describe connection
-                                                </a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/describe.html#topic_C635B500BE6A4F1D9572D0BC98A224F2">describe disk-store</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/describe.html#describe_jndi-binding">describe jndi-binding</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/describe.html#describe_lucene_index">describe lucene index</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/describe.html#topic_D62F3D42B1D84CF68F03D54D5122806A">describe member</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/describe.html#topic_kys_yvk_2l">describe offline-disk-store</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/describe.html#topic_describe_query_service">describe query-service</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/describe.html#topic_DECF7D3D33F54071B6B8AD4EA7E3F90B">describe region
-                                                </a>
-                                            </li>
-                                        </ul>
-                                    </li>
-                                    <li class="has_submenu">
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/destroy.html">destroy</a>
-                                        <ul>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/destroy.html#topic_destroy-async-event-queue">destroy async-event-queue</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/destroy.html#topic_yfr_l2z_ck">destroy disk-store</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/destroy.html#topic_E48C2DF809054C12A162026D8A2139BB">destroy function</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/destroy.html#destroy-gr">destroy gateway-receiver</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/destroy.html#destroy-gs">destroy gateway-sender</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/destroy.html#topic_D00219CCD6F64C1582A0802AC5CDF3F3">destroy index</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/destroy.html#destroy_jndi-binding">destroy jndi-binding</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/destroy.html#destroy_lucene_index">destroy lucene index</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/destroy.html#topic_BEDACECF4599407794ACBC0E56B30F65">destroy region</a>
-                                            </li>
-                                        </ul>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/disconnect.html">disconnect</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/echo.html">echo</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/execute.html">execute function</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/exit.html">exit</a>
-                                    </li>
-                                    <li class="has_submenu">
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/export.html">export</a>
-                                        <ul>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/export.html#topic_mdv_jgz_ck">export cluster-configuration
-                                                </a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/export.html#topic_C7C69306F93743459E65D46537F4A1EE">export config</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/export.html#topic_263B70069BFC4A7185F86B3272011734">export data</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/export.html#topic_B80978CC659244AE91E2B8CE56EBDFE3">export logs</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/export.html#topic_sjg_bvt_gq">export offline-disk-store</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/export.html#topic_195D27B8B2B64A4E84CF2256636D54BD">export stack-traces</a>
-                                            </li>
-                                        </ul>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/gc.html">gc</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/get.html">get</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/help.html">help</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/hint.html">hint</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/history.html">history</a>
-                                    </li>
-                                    <li class="has_submenu">
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/import.html">import</a>
-                                        <ul>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/import.html#topic_vnv_grz_ck">import cluster-configuration</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/import.html#topic_jw2_2ld_2l">import data</a>
-                                            </li>
-                                        </ul>
-                                    </li>
-                                    <li class="has_submenu">
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/list.html">list</a>
-                                        <ul>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/list.html#topic_j22_kzk_2l">list async-event-queues</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/list.html#topic_ts1_qb1_dk">list clients</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/list.html#topic_59DF60DE71AD4097B281749425254BFF">list deployed
-                                                </a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/list.html#topic_BC14AD57EA304FB3845766898D01BD04">list disk-stores</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/list.html#topic_66016A698C334F4EBA19B99F51B0204B">list durable-cqs</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/list.html#topic_DCC7CCBBEF5942B783A8F2A4A5B2FABF">list functions</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/list.html#topic_B1D89671C7B74074899C7D52F15849ED">list gateways</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/list.html#topic_B3B51B6DEA484EE086C4F657EC9831F2">list indexes</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/list.html#list_jndi-binding">list jndi-binding</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/list.html#list_lucene_indexes">list lucene indexes</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/list.html#topic_5B5BFB2E5F314210858641BE3A689637">list members</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/list.html#topic_F0ECEFF26086474498598035DD83C588">list regions</a>
-                                            </li>
-                                        </ul>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/load-balance.html">load-balance gateway-sender</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/locate.html">locate entry</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/netstat.html">netstat</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/pause.html">pause gateway-sender</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/pdx.html">pdx rename</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/put.html">put</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/query.html">query</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/rebalance.html">rebalance</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/remove.html">remove</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/restore.html">restore redundancy</a>
-                                    </li>
-                                    <li class="has_submenu">
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/resume.html">resume</a>
-                                        <ul>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/resume.html#topic_resume_async_event_queue_dispatcher">resume async-event-queue-dispatcher</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/resume.html#topic_resume_gateway_sender">resume gateway-sender</a>
-                                            </li>
-                                        </ul>
-                                        </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/revoke.html">revoke missing-disk-store</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/run.html">run</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/search.html">search lucene</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/set.html">set variable</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/sh.html">sh</a>
-                                    </li>
-                                    <li class="has_submenu">
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/show.html">show</a>
-                                        <ul>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/show.html#topic_1225347FAD6541DF995C9999650165B1">show dead-locks</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/show.html#topic_45AAEDAC3AFF46EC9BB68B24FC9A32B3">show log</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/show.html#topic_6EB786C63AEB46179EEE8FA18624295A">show metrics</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/show.html#topic_7B3D624D5B4F41D1A0F8A9C3C8B2E780">show missing-disk-stores</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/show.html#topic_395C96B500AD430CBF3D3C8886A4CD2E">show subscription-queue-size</a>
-                                            </li>
-                                        </ul>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/shutdown.html">shutdown</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/sleep.html">sleep</a>
-                                    </li>
-                                    <li class="has_submenu">
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/start.html">start</a>
-                                        <ul>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/start.html#topic_67738A5B68E84DEE95D1C92DAB2E26E5">start gateway-receiver</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/start.html#topic_AB8BA3F42B9645A8BE9BD97CE2F839A8">start gateway-sender</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/start.html#topic_D00507416F3944DFAB48D2FA2B9E4A31">start jconsole</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/start.html#topic_5B5BF8BEE905463D8B7762B89E2D65E7">start jvisualvm
-                                                </a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/start.html#topic_591260CF25D64562A0EDD7260D2AC6D4">start locator</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/start.html#topic_E906BA7D9E7F4C5890FEFA7ECD40DD77">start pulse</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/start.html#topic_3764EE2DB18B4AE4A625E0354471738A">start server</a>
-                                            </li>
-                                        </ul>
-                                    </li>
-                                    <li class="has_submenu">
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/status.html">status</a>
-                                        <ul>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/status.html#topic_ts1_qb1_dk2">status cluster-config-service</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/status.html#topic_B0F45DC2D5F64FB1A2F738206BC6539E">status gateway-receiver</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/status.html#topic_6F539877F0564F05AF264A9E704EC842">status gateway-sender</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/status.html#topic_E96D0EFA513C4CD79B833FCCDD69C832">status locator</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/status.html#topic_status_redundancy">status redundancy</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/status.html#topic_E5DB49044978404D9D6B1971BF5D400D">status server</a>
-                                            </li>
-                                        </ul>
-                                    </li>
-                                    <li class="has_submenu">
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/stop.html">stop</a>
-                                        <ul>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/stop.html#topic_CD1D526FD6F84A7B80B25C741229ED30">stop gateway-receiver
-                                                </a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/stop.html#topic_0BBDD4B3B8A44A65A610F766C9E85519">stop gateway-sender</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/stop.html#topic_EF61C54B35BA4AB7B14E58CF912F283E">stop locator</a>
-                                            </li>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/stop.html#topic_723EE395A63A40D6819618AFC2902125">stop server</a>
-                                            </li>
-                                        </ul>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/undeploy.html">undeploy</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/validate.html">validate offline-disk-store</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command-pages/version.html">version</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/command_scripting.html">Creating and Running gfsh Command Scripts</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/os_command_line_execution.html">Running gfsh Commands on the OS Command Line</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gfsh/cache_xml_2_gfsh.html">Mapping cache.xml Elements to gfsh Configuration Commands</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gemcached/chapter_overview.html">Gemcached</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gemcached/about_gemcached.html">How Gemcached Works</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gemcached/deploying_gemcached.html">Deploying and Configuring a Gemcached Server</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/gemcached/advantages.html">Advantages of Gemcached over Memcached</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/http_session_mgmt/chapter_overview.html">HTTP Session Management Modules</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/http_session_mgmt/quick_start.html">HTTP Session Management Quick Start</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/http_session_mgmt/http_why_use_gemfire.html">Advantages of Using Geode for Session Management</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/http_session_mgmt/common_gemfire_topologies.html">Common Topologies for HTTP Session Management</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/http_session_mgmt/tc_additional_info.html">General Information on HTTP Session Management</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/http_session_mgmt/session_state_log_files.html">Session State Log Files</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/http_session_mgmt/configuring_non_sticky_sessions.html">Configuring Non-Sticky Sessions</a>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/http_session_mgmt/session_mgmt_tcserver.html">HTTP Session Management Module for Pivotal tc Server</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/http_session_mgmt/tc_installing_the_module.html">Installing the HTTP Module for tc Server</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/http_session_mgmt/tc_setting_up_the_module.html">Setting Up the HTTP Module for tc Server</a>
-                                    </li>
-                                    <li class="has_submenu">
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/http_session_mgmt/tc_changing_gf_default_cfg.html">Changing the Default Geode Configuration in the tc Server Module</a>
-                                        <ul>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/http_session_mgmt/interactive_mode_ref.html">Interactive Configuration Reference for the tc Server Module
-                                                </a>
-                                            </li>
-                                        </ul>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/http_session_mgmt/session_mgmt_tomcat.html">HTTP Session Management Module for Tomcat</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/http_session_mgmt/tomcat_installing_the_module.html">Installing the HTTP Module for Tomcat</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/http_session_mgmt/tomcat_setting_up_the_module.html">Setting Up the HTTP Module for Tomcat</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/http_session_mgmt/tomcat_changing_gf_default_cfg.html">Changing the Default Geode Configuration in the Tomcat Module</a>
-                                    </li>
-                                </ul>
-                            </li>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/http_session_mgmt/session_mgmt_weblogic.html">HTTP Session Management Module for AppServers</a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/http_session_mgmt/weblogic_setting_up_the_module.html">Setting Up the HTTP Module for AppServers
-                                        </a>
-                                    </li>
-                                    <li class="has_submenu">
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/http_session_mgmt/weblogic_changing_gf_default_cfg.html">Changing the Default Geode Configuration in the AppServers Module
-                                        </a>
-                                        <ul>
-                                            <li>
-                                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/http_session_mgmt/weblogic_common_configuration_changes.html">Common Geode Configuration Changes for AppServers</a>
-                                            </li>
-                                        </ul>
-                                    </li>
-                                </ul>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/pulse/pulse-overview.html">Geode Pulse</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/pulse/pulse-requirements.html">Pulse System Requirements</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/pulse/pulse-embedded.html">Running Pulse in Embedded Mode (Quick Start)</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/pulse/pulse-hosted.html">Hosting Pulse on a Web Application Server</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/pulse/pulse-auth.html">Configuring Pulse Authentication</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/pulse/pulse-views.html">Using Pulse Views</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/redis_api_for_geode.html">Redis API for <%=vars.product_name%></a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/redis_api_for_geode.html#using-the-api">Using the Redis API for <%=vars.product_name%></a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/redis_api_for_geode.html#included-commands">Included Redis Commands</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/redis_api_for_geode.html#advantages-over-redis">Advantages of <%=vars.product_name%> over Redis</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/redis_api_for_geode.html#expiration-accuracy">Expiration Accuracy</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/lucene_integration.html">Apache Lucene Integration</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/lucene_integration.html#using-the-apache-lucene-integration">Using the Apache Lucene Integration</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/lucene_integration.html#LuceneRandC">Requirements and Caveats</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/micrometer/micrometer-overview.html">Micrometer</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/micrometer/micrometer-configuration.html">Configuration and Publishing</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/tools_modules/micrometer/micrometer-meters.html">Micrometer Meters and Tags</a>
-                            </li>
-                        </ul>
-                    </li>
-                </ul>
-            </li>
-            <li class="has_submenu">
-                <a href="/docs/guide/<%=vars.product_version_nodot%>/use_cases/book_intro.html">Use Cases</a>
-                <ul>
-                    <li>
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/use_cases/inline-cache.html">The Inline Cache</a>
-                    </li>
-                </ul>
-            </li>
-            <li class="has_submenu">
-                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/book_intro.html">Reference</a>
-                <ul>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/gemfire_properties.html">gemfire.properties and gfsecurity.properties (Geode Properties)</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/non-ascii_strings_in_config_files.html">Using Non-ASCII Strings in Apache Geode Property Files</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/chapter_overview_cache_xml.html">cache.xml
-                        </a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/elements_ref.html">cache.xml Quick Reference</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/cache-elements-list.html">&lt;cache&gt; Element Hierarchy</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/cache_xml.html">&lt;cache&gt; Element Reference</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/client-cache-elements-list.html">
-                                    &lt;client-cache&gt; Element Hierarchy</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/client-cache.html">&lt;client-cache&gt; Element Reference</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/chapter_overview_regionshortcuts.html">Region Shortcuts</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/region_shortcuts_table.html">Region Shortcuts Quick Reference</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/region_shortcuts_reference.html#reference_w2h_3cd_lk">
-                                    LOCAL
-                                </a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/region_shortcuts_reference.html#reference_wd5_lpy_lk">
-                                    LOCAL_HEAP_LRU
-                                </a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/region_shortcuts_reference.html#reference_adk_y4y_lk">
-                                    LOCAL_OVERFLOW
-                                </a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/region_shortcuts_reference.html#reference_l5r_y4y_lk">
-                                    LOCAL_PERSISTENT
-                                </a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/region_shortcuts_reference.html#reference_a45_y4y_lk">
-                                    LOCAL_PERSISTENT_OVERFLOW
-                                </a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/region_shortcuts_reference.html#reference_ow5_4qy_lk">
-                                    PARTITION
-                                </a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/region_shortcuts_reference.html#reference_twx_y4y_lk">
-                                    PARTITION_HEAP_LRU
-                                </a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/region_shortcuts_reference.html#reference_js1_z4y_lk">
-                                    PARTITION_OVERFLOW
-                                </a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/region_shortcuts_reference.html#reference_d4k_jpy_lk">
-                                    PARTITION_PERSISTENT
-                                </a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/region_shortcuts_reference.html#reference_v5l_jpy_lk">
-                                    PARTITION_PERSISTENT_OVERFLOW
-                                </a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/region_shortcuts_reference.html#reference_v4m_jpy_lk">
-                                    PARTITION_PROXY
-                                </a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/region_shortcuts_reference.html#reference_c1n_jpy_lk">
-                                    PARTITION_PROXY_REDUNDANT
-                                </a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/region_shortcuts_reference.html#reference_shn_jpy_lk">
-                                    PARTITION_REDUNDANT
-                                </a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/region_shortcuts_reference.html#reference_m4n_jpy_lk">
-                                    PARTITION_REDUNDANT_HEAP_LRU
-                                </a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/region_shortcuts_reference.html#reference_own_jpy_lk">
-                                    PARTITION_REDUNDANT_OVERFLOW
-                                </a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/region_shortcuts_reference.html#reference_bd4_jpy_lk">
-                                    PARTITION_REDUNDANT_PERSISTENT
-                                </a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/region_shortcuts_reference.html#reference_xqq_tvc_lk">
-                                    PARTITION_REDUNDANT_PERSISTENT_OVERFLOW
-                                </a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/region_shortcuts_reference.html#reference_wq4_jpy_lk">
-                                    REPLICATE
-                                </a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/region_shortcuts_reference.html#reference_xx4_jpy_lk">
-                                    REPLICATE_HEAP_LRU
-                                </a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/region_shortcuts_reference.html#reference_t2p_jpy_lk">
-                                    REPLICATE_OVERFLOW
-                                </a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/region_shortcuts_reference.html#reference_emp_jpy_lk">
-                                    REPLICATE_PERSISTENT
-                                </a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/region_shortcuts_reference.html#reference_tsp_jpy_lk">
-                                    REPLICATE_PERSISTENT_OVERFLOW
-                                </a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/region_shortcuts_reference.html#reference_n1q_jpy_lk">
-                                    REPLICATE_PROXY
-                                </a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li>
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/handling_exceptions_and_failures.html">
-                            Exceptions and System Failures</a>
-                    </li>
-                    <li>
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/memory_requirements_for_cache_data.html">Memory Requirements for Cached Data</a>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/statistics_list.html">Geode Statistics List</a>
-                        <ul>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/statistics_list.html#section_DEF8D3644D3246AB8F06FE09A37DC5C8">Cache Performance (CachePerfStats)</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/statistics_list.html#section_EF5C2C59BFC74FFB8607F9571AB9A471">Cache Server (CacheServerStats)</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/statistics_list.html#section_B08C0783BBF9489E8BB48B4AEC597C62">Client-Side Notifications (CacheClientUpdaterStats)</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/statistics_list.html#section_04B7D7387E584712B7710B5ED1E876BB">Client-to-Server Messaging Performance (ClientStats)</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/statistics_list.html#section_6C247F61DB834C079A16BE92789D4692">Client Connection Pool (PoolStats)</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/statistics_list.html#section_66C0E7748501480B85209D57D24256D5">Continuous Querying (CQStatistics)</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/statistics_list.html#section_D4ABED3FF94245C0BEE0F6FC9481E867">Delta Propagation (DeltaPropagationStatistics)</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/statistics_list.html#section_6C2BECC63A83456190B029DEDB8F4BE3">Disk Space Usage (DiskDirStatistics)</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/statistics_list.html#section_983BFC6D53C74829A04A91C39E06315F">Disk Usage and Performance (DiskRegionStatistics)</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/statistics_list.html#section_ACB4161F10D64BC0B15871D003FF6FDF">Distributed System Messaging (DistributionStats)</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/statistics_list.html#section_78D346A580724E1EA645E31626EECE40">Distributed Lock Services (DLockStats)</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/statistics_list.html#section_5E212DDB0E8640689AD0A4659512E17A">Function Execution (FunctionServiceStatistics)</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/statistics_list.html#section_C4199A541B1F4B82B6178C416C0FAE4B">Gateway Queue (GatewayStatistics)</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/statistics_list.html#section_86A61860024B480592DAC67FFB882538">Indexes (IndexStats)</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/statistics_list.html#section_607C3867602E410CAE5FAB26A7FF1CB9">JVM Performance</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/statistics_list.html#section_C48B654F973E4B44AD825D459C23A6CD">Locator (LocatorStatistics)</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/statistics_list.html#LuceneStats">Lucene Indexes (LuceneIndexStats)</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/statistics_list.html#topic_ohc_tjk_w5">Off-Heap (OffHeapMemoryStats)</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/statistics_list.html#section_923B28F01BC3416786D3AFBD87F22A5E">Operating System Statistics - Linux</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/statistics_list.html#section_35AC170770C944C3A336D9AEC2D2F7C5">Partitioned Regions (PartitionedRegion&lt;partitioned_region_name&gt;Statistics)</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/statistics_list.html#section_374FBD92A3B74F6FA08AA23047929B4F">Region Entry Eviction – Count-Based (LRUStatistics)
-                                </a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/statistics_list.html#section_3D2AA2BCE5B6485699A7B6ADD1C49FF7">Region Entry Eviction – Size-based (LRUStatistics)</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/statistics_list.html#section_5362EF9AECBC48D69475697109ABEDFA">Server Notifications for All Clients (CacheClientNotifierStatistics)</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/statistics_list.html#section_E03865F509E543D9B8F9462B3DA6255E">Server Notifications for Single Client (CacheClientProxyStatistics)</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/statistics_list.html#section_3AB1C0AA55014163A2BBF68E13D25E3A">Server-to-Client Messaging Performance (ClientSubscriptionStats)</a>
-                            </li>
-                            <li>
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/statistics_list.html#section_55F3AF6413474317902845EE4996CC21">Statistics Collection (StatSampler)</a>
-                            </li>
-                        </ul>
-                    </li>
-                    <li class="has_submenu">
-                        <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/archive_transactions/chapter_overview.html">Transaction Reference Material</a>
-                        <ul>
-                            <li class="has_submenu">
-                                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/archive_transactions/JTA_transactions.html">JTA Global Transactions with Geode
-                                </a>
-                                <ul>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/archive_transactions/JTA_transactions.html#concept_cp1_zx1_wk">Coordinating with External JTA Transaction Managers</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/archive_transactions/JTA_transactions.html#concept_csy_vfb_wk">Using Geode as the "Last Resource" in a Container-Managed JTA Transaction</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/archive_transactions/cache_plugins_with_jta.html">Behavior of Geode Cache Writers and Loaders Under JTA</a>
-                                    </li>
-                                    <li>
-                                        <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/archive_transactions/turning_off_jta.html">Turning Off JTA Transactions
-                                        </a>
-                                    </li>
-                                </ul>
-                            </li>
-                        </ul>
-                    </li>
-                </ul>
-            </li>
-            <li>
-                <a href="/docs/guide/<%=vars.product_version_nodot%>/reference/topics/glossary.html">Glossary</a>
-            </li>
-        </ul>
-    </div>
-</div>
diff --git a/geode-book/redirects.rb b/geode-book/redirects.rb
deleted file mode 100644
index a0b36c9..0000000
--- a/geode-book/redirects.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-#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.
-
-r301 %r{/releases/latest/javadoc/(.*)}, 'http://geode.apache.org/releases/latest/javadoc/$1'
-rewrite '/', '/docs/guide/114/about_geode.html'
-rewrite '/index.html', '/docs/guide/114/about_geode.html'
diff --git a/geode-common-services/build.gradle b/geode-common-services/build.gradle
index 6225974..4f9fc96 100644
--- a/geode-common-services/build.gradle
+++ b/geode-common-services/build.gradle
@@ -27,43 +27,9 @@ repositories {
 dependencies {
     compile(platform(project(':boms:geode-all-bom')))
 
-    compile('org.apache.commons:commons-lang3')
+    implementation('org.apache.commons:commons-lang3')
 
-    compile(project(':geode-common'))
-}
-
-def geodeProjects = ['geode-common-services', 'geode-common']
-
-jar {
-    doFirst {
-        def projectDependencies = []
-        def runtimeList = []
-
-        configurations.runtimeClasspath
-                .collect { it.name - ".jar" }
-                .each { dependency ->
-                    if (dependency.startsWith("geode-")) {
-                        projectDependencies.add(dependency)
-                    } else {
-                        runtimeList.add(dependency)
-                    }
-                }
+    implementation(project(':geode-common'))
 
-        projectDependencies.each { projectDependency ->
-            geodeProjects.each { geodeProject ->
-                if (projectDependency.contains(geodeProject)) {
-                    def parentProject = project(":$geodeProject")
-                    if (parentProject != null) {
-                        def collect = parentProject.configurations.runtimeClasspath.collect { it.name - ".jar" }
-                        runtimeList.removeAll(collect)
-                        projectDependencies.removeAll(collect)
-                    }
-                }
-            }
-        }
-        manifest {
-            attributes("Class-Path": runtimeList.join(' '))
-            attributes("Dependent-Modules": projectDependencies.join(' '))
-        }
-    }
+    implementation(project(':geode-logging'))
 }
diff --git a/geode-common-services/src/main/java/org/apache/geode/services/bootstrapping/BootstrappingService.java b/geode-common-services/src/main/java/org/apache/geode/services/bootstrapping/BootstrappingService.java
index d23acc7..f63812a 100644
--- a/geode-common-services/src/main/java/org/apache/geode/services/bootstrapping/BootstrappingService.java
+++ b/geode-common-services/src/main/java/org/apache/geode/services/bootstrapping/BootstrappingService.java
@@ -18,6 +18,7 @@ package org.apache.geode.services.bootstrapping;
 import java.util.Properties;
 
 import org.apache.geode.annotations.Experimental;
+import org.apache.geode.services.module.ModuleService;
 
 /**
  * Service responsible for bootstrapping the environment and Geode components.
@@ -31,14 +32,12 @@ public interface BootstrappingService {
    * Start and initialize Geode.
    *
    * @param properties system properties to use when bootstrapping the environment.
-   * @throws Exception - thrown if unable to bootstrap system.
    */
-  void init(Properties properties) throws Exception;
+  void init(ModuleService moduleService, Properties properties);
 
   /**
    * Shuts down the environment and previously bootstrapped Geode components.
    *
-   * @throws Exception - thrown if unable to shutdown.
    */
-  void shutdown() throws Exception;
+  void shutdown();
 }
diff --git a/geode-common-services/src/main/java/org/apache/geode/services/management/ManagementService.java b/geode-common-services/src/main/java/org/apache/geode/services/management/ManagementService.java
index 5ae23c5..7cc3f39 100644
--- a/geode-common-services/src/main/java/org/apache/geode/services/management/ManagementService.java
+++ b/geode-common-services/src/main/java/org/apache/geode/services/management/ManagementService.java
@@ -15,7 +15,11 @@
 
 package org.apache.geode.services.management;
 
+import java.util.Properties;
+
 import org.apache.geode.annotations.Experimental;
+import org.apache.geode.services.module.ModuleService;
+import org.apache.geode.services.result.ModuleServiceResult;
 
 /**
  * Entry point for creating a cache and bootstrapping Geode using the BootstrappingService
@@ -25,6 +29,8 @@ import org.apache.geode.annotations.Experimental;
 @Experimental
 public interface ManagementService {
 
+  void init(ModuleService moduleService);
+
   /**
    * Creates a Geode Cache given some configuration.
    *
@@ -32,5 +38,5 @@ public interface ManagementService {
    *
    * @throws Exception is Cache cannot be created.
    */
-  // Cache createCache(Properties properties) throws Exception;
+  ModuleServiceResult<Boolean> createCache(Properties properties);
 }
diff --git a/geode-common-services/src/main/java/org/apache/geode/services/module/ModuleDescriptor.java b/geode-common-services/src/main/java/org/apache/geode/services/module/ModuleDescriptor.java
index dc8182d..dd7918d 100644
--- a/geode-common-services/src/main/java/org/apache/geode/services/module/ModuleDescriptor.java
+++ b/geode-common-services/src/main/java/org/apache/geode/services/module/ModuleDescriptor.java
@@ -46,12 +46,15 @@ public class ModuleDescriptor {
   // A collection of module names on which this module depends on
   private final Set<String> dependencies;
 
+  private final boolean requiresJDKPaths;
+
   private ModuleDescriptor(String name, String version, Set<String> resourceJarPaths,
-      Set<String> dependencies) {
+      Set<String> dependencies, boolean requiresJDKPaths) {
     this.name = name;
     this.version = version;
     this.resourceJarPaths = resourceJarPaths;
     this.dependencies = dependencies;
+    this.requiresJDKPaths = requiresJDKPaths;
   }
 
   /**
@@ -82,6 +85,10 @@ public class ModuleDescriptor {
     return name + (version != null ? "-" + version : "");
   }
 
+  public boolean requiresJDKPaths() {
+    return requiresJDKPaths;
+  }
+
   /**
    * A Builder used to construct a {@link ModuleDescriptor}
    */
@@ -91,6 +98,7 @@ public class ModuleDescriptor {
     private final String version;
     private final Set<String> dependencies = new HashSet<>();
     private final Set<String> sources = new HashSet<>();
+    private boolean requiresJDKPaths = false;
 
     public Builder(String name) {
       this(name, null);
@@ -116,7 +124,7 @@ public class ModuleDescriptor {
     }
 
     public Builder dependsOnModules(String... dependencies) {
-      return this.dependsOnModules(Arrays.asList(dependencies));
+      return dependsOnModules(Arrays.asList(dependencies));
     }
 
     public Builder dependsOnModules(Collection<String> dependencies) {
@@ -124,8 +132,13 @@ public class ModuleDescriptor {
       return this;
     }
 
+    public Builder requiresJDKPaths(boolean requiresJDKPaths) {
+      this.requiresJDKPaths = requiresJDKPaths;
+      return this;
+    }
+
     public ModuleDescriptor build() {
-      return new ModuleDescriptor(name, version, sources, dependencies);
+      return new ModuleDescriptor(name, version, sources, dependencies, requiresJDKPaths);
     }
   }
 }
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 e6c693c..84e3c11 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
@@ -15,9 +15,12 @@
 
 package org.apache.geode.services.module;
 
-import java.util.Map;
+import java.io.InputStream;
+import java.util.List;
 import java.util.Set;
 
+import org.apache.logging.log4j.Logger;
+
 import org.apache.geode.annotations.Experimental;
 import org.apache.geode.services.result.ModuleServiceResult;
 
@@ -90,7 +93,7 @@ public interface ModuleService {
    *         used {@link ModuleServiceResult#getErrorMessage()} to get the error message of the
    *         failure.
    */
-  <T> ModuleServiceResult<Map<String, Set<T>>> loadService(Class<T> service);
+  <T> ModuleServiceResult<Set<T>> loadService(Class<T> service);
 
   /**
    * Returns the Class for the provided name for a specific module.
@@ -120,5 +123,9 @@ public interface ModuleService {
    *         used {@link ModuleServiceResult#getErrorMessage()} to get the error message of the
    *         failure.
    */
-  ModuleServiceResult<Map<String, Class<?>>> loadClass(String className);
+  ModuleServiceResult<List<Class<?>>> loadClass(String className);
+
+  ModuleServiceResult<List<InputStream>> findResourceAsStream(String resourceFile);
+
+  void setLogger(Logger logger);
 }
diff --git a/geode-common-services/src/main/java/org/apache/geode/services/module/impl/ServiceLoaderModuleService.java b/geode-common-services/src/main/java/org/apache/geode/services/module/impl/ServiceLoaderModuleService.java
new file mode 100644
index 0000000..dadeb75
--- /dev/null
+++ b/geode-common-services/src/main/java/org/apache/geode/services/module/impl/ServiceLoaderModuleService.java
@@ -0,0 +1,116 @@
+/*
+ * 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.geode.services.module.impl;
+
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ServiceLoader;
+import java.util.Set;
+
+import org.apache.logging.log4j.Logger;
+
+import org.apache.geode.services.module.ModuleDescriptor;
+import org.apache.geode.services.module.ModuleService;
+import org.apache.geode.services.result.ModuleServiceResult;
+import org.apache.geode.services.result.impl.Failure;
+import org.apache.geode.services.result.impl.Success;
+
+public class ServiceLoaderModuleService implements ModuleService {
+
+  private Logger logger;
+
+  public ServiceLoaderModuleService(Logger logger) {
+    this.logger = logger;
+  }
+
+  @Override
+  public ModuleServiceResult<Boolean> loadModule(ModuleDescriptor moduleDescriptor) {
+    return Failure.of("This features is not implemented for a default ModuleService");
+  }
+
+  @Override
+  public ModuleServiceResult<Boolean> registerModule(ModuleDescriptor moduleDescriptor) {
+    return Failure.of("This features is not implemented for a default ModuleService");
+  }
+
+  @Override
+  public ModuleServiceResult<Boolean> unloadModule(String moduleName) {
+    return Failure.of("This features is not implemented for a default ModuleService");
+  }
+
+  @Override
+  public <T> ModuleServiceResult<Set<T>> loadService(Class<T> service) {
+    Set<T> result = new HashSet<>();
+    try {
+      Iterator<T> iterator = ServiceLoader.load(service).iterator();
+      while (iterator.hasNext()) {
+        try {
+          result.add(iterator.next());
+        } catch (Error e) {
+          logger.error(e.getMessage());
+        }
+      }
+    } catch (Exception e) {
+      return Failure.of(e.toString());
+    }
+    return Success.of(result);
+  }
+
+  @Override
+  public ModuleServiceResult<Class<?>> loadClass(String className,
+      ModuleDescriptor moduleDescriptor) {
+    return Failure.of("This features is not implemented for a default ModuleService");
+  }
+
+  @Override
+  public ModuleServiceResult<List<Class<?>>> loadClass(String className) {
+    try {
+      return Success.of(Collections.singletonList(
+          this.getClass().getClassLoader().loadClass(className)));
+    } catch (ClassNotFoundException e) {
+      return Failure.of(e.toString());
+    }
+  }
+
+  @Override
+  public ModuleServiceResult<List<InputStream>> findResourceAsStream(String resourceFile) {
+    InputStream inputStream = null;
+    ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
+    if (contextClassLoader != null) {
+      inputStream = contextClassLoader.getResourceAsStream(resourceFile);
+    }
+
+    if (inputStream == null) {
+      inputStream = getClass().getResourceAsStream(resourceFile);
+    }
+    if (inputStream == null) {
+      inputStream = ClassLoader.getSystemResourceAsStream(resourceFile);
+    }
+
+    return inputStream == null
+        ? Failure.of(String.format("No resource for path: %s could be found", resourceFile))
+        : Success.of(Collections.singletonList(inputStream));
+  }
+
+  @Override
+  public void setLogger(Logger logger) {
+    this.logger = logger;
+  }
+}
diff --git a/geode-modules/src/main/java/org/apache/geode/services/result/impl/Failure.java b/geode-common-services/src/main/java/org/apache/geode/services/result/impl/Failure.java
similarity index 100%
rename from geode-modules/src/main/java/org/apache/geode/services/result/impl/Failure.java
rename to geode-common-services/src/main/java/org/apache/geode/services/result/impl/Failure.java
diff --git a/geode-modules/src/main/java/org/apache/geode/services/result/impl/Success.java b/geode-common-services/src/main/java/org/apache/geode/services/result/impl/Success.java
similarity index 100%
rename from geode-modules/src/main/java/org/apache/geode/services/result/impl/Success.java
rename to geode-common-services/src/main/java/org/apache/geode/services/result/impl/Success.java
diff --git a/geode-common-services/src/test/resources/expected-pom.xml b/geode-common-services/src/test/resources/expected-pom.xml
index dbc47ae..26f1cdd 100644
--- a/geode-common-services/src/test/resources/expected-pom.xml
+++ b/geode-common-services/src/test/resources/expected-pom.xml
@@ -19,7 +19,7 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>org.apache.geode</groupId>
   <artifactId>geode-common-services</artifactId>
-  <version>${version}</version>
+  <version>1.13.0-SNAPSHOT</version>
   <name>Apache Geode</name>
   <description>Apache Geode provides a database-like consistency model, reliable transaction processing and a shared-nothing architecture to maintain very low latency performance with high concurrency processing</description>
   <url>http://geode.apache.org</url>
@@ -39,7 +39,7 @@
       <dependency>
         <groupId>org.apache.geode</groupId>
         <artifactId>geode-all-bom</artifactId>
-        <version>${version}</version>
+        <version>1.13.0-SNAPSHOT</version>
         <type>pom</type>
         <scope>import</scope>
       </dependency>
@@ -47,13 +47,13 @@
   </dependencyManagement>
   <dependencies>
     <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-lang3</artifactId>
+      <groupId>org.apache.geode</groupId>
+      <artifactId>geode-common</artifactId>
       <scope>compile</scope>
     </dependency>
     <dependency>
       <groupId>org.apache.geode</groupId>
-      <artifactId>geode-common</artifactId>
+      <artifactId>geode-core</artifactId>
       <scope>compile</scope>
     </dependency>
   </dependencies>
diff --git a/geode-common/build.gradle b/geode-common/build.gradle
index a8b59b3..52007bd 100755
--- a/geode-common/build.gradle
+++ b/geode-common/build.gradle
@@ -26,40 +26,3 @@ dependencies {
   testImplementation('junit:junit')
   testImplementation('org.assertj:assertj-core')
 }
-
-def geodeProjects = ['geode-common-services','geode-common']
-
-jar {
-  doFirst {
-    def projectDependencies = []
-    def runtimeList = []
-
-    configurations.runtimeClasspath
-            .collect { it.name - ".jar" }
-            .each { dependency ->
-              if (dependency.startsWith("geode-")) {
-                projectDependencies.add(dependency)
-              } else {
-                runtimeList.add(dependency)
-              }
-            }
-
-    projectDependencies.each { projectDependency ->
-      geodeProjects.each { geodeProject ->
-        if (projectDependency.contains(geodeProject)) {
-          def childProject = project(":$geodeProject")
-
-          if (childProject != null) {
-            def collect = childProject.configurations.runtimeClasspath.collect { it.name - ".jar" }
-            runtimeList.removeAll(collect)
-            projectDependencies.removeAll(collect)
-          }
-        }
-      }
-    }
-    manifest {
-      attributes("Class-Path": runtimeList.join(' '))
-      attributes("Dependent-Modules": projectDependencies.join(' '))
-    }
-  }
-}
diff --git a/geode-connectors/build.gradle b/geode-connectors/build.gradle
index 285c425..c0fed4d 100644
--- a/geode-connectors/build.gradle
+++ b/geode-connectors/build.gradle
@@ -57,6 +57,11 @@ dependencies {
   implementation('org.apache.httpcomponents:httpcore')
   implementation('com.fasterxml.jackson.core:jackson-databind')
 
+  testImplementation(project(":geode-modules"))
+  integrationTestImplementation(project(":geode-modules"))
+  acceptanceTestImplementation(project(":geode-modules"))
+  distributedTestImplementation(project(":geode-modules"))
+
   testImplementation(project(':geode-membership'))
   testImplementation(project(':geode-junit')) {
     exclude module: 'geode-core'
diff --git a/geode-connectors/src/acceptanceTest/java/org/apache/geode/connectors/jdbc/internal/TestConfigService.java b/geode-connectors/src/acceptanceTest/java/org/apache/geode/connectors/jdbc/internal/TestConfigService.java
index 2f7162f..edc1b80 100644
--- a/geode-connectors/src/acceptanceTest/java/org/apache/geode/connectors/jdbc/internal/TestConfigService.java
+++ b/geode-connectors/src/acceptanceTest/java/org/apache/geode/connectors/jdbc/internal/TestConfigService.java
@@ -24,6 +24,8 @@ import org.apache.geode.connectors.jdbc.internal.configuration.FieldMapping;
 import org.apache.geode.connectors.jdbc.internal.configuration.RegionMapping;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.cache.extension.ExtensionPoint;
+import org.apache.geode.logging.internal.log4j.api.LogService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 
 /**
  * Generates fake JdbcConnectorService for tests.
@@ -45,7 +47,7 @@ public class TestConfigService {
       throws RegionMappingExistsException {
 
     JdbcConnectorServiceImpl service = new JdbcConnectorServiceImpl();
-    service.init(cache);
+    service.init(cache, new ServiceLoaderModuleService(LogService.getLogger()));
     service.createRegionMapping(
         createRegionMapping(pdxClassName, ids, catalog, schema, fieldMappings));
     return service;
diff --git a/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyDataSourceCommandDUnitTest.java b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyDataSourceCommandDUnitTest.java
index f1e3855..8f213c8 100644
--- a/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyDataSourceCommandDUnitTest.java
+++ b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/DestroyDataSourceCommandDUnitTest.java
@@ -34,11 +34,13 @@ import org.w3c.dom.NodeList;
 import org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
 import org.apache.geode.distributed.internal.InternalLocator;
 import org.apache.geode.internal.jndi.JNDIInvoker;
+import org.apache.geode.logging.internal.log4j.api.LogService;
 import org.apache.geode.management.internal.configuration.domain.Configuration;
 import org.apache.geode.management.internal.configuration.utils.XmlUtils;
 import org.apache.geode.pdx.PdxReader;
 import org.apache.geode.pdx.PdxSerializable;
 import org.apache.geode.pdx.PdxWriter;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 import org.apache.geode.test.dunit.rules.ClusterStartupRule;
 import org.apache.geode.test.dunit.rules.MemberVM;
 import org.apache.geode.test.junit.rules.GfshCommandRule;
@@ -89,7 +91,9 @@ public class DestroyDataSourceCommandDUnitTest {
       InternalConfigurationPersistenceService ccService =
           internalLocator.getConfigurationPersistenceService();
       Configuration configuration = ccService.getConfiguration("cluster");
-      Document document = XmlUtils.createDocumentFromXml(configuration.getCacheXmlContent());
+      Document document =
+          XmlUtils.createDocumentFromXml(configuration.getCacheXmlContent(),
+              new ServiceLoaderModuleService(LogService.getLogger()));
       NodeList jndiBindings = document.getElementsByTagName("jndi-binding");
 
       AssertionsForClassTypes.assertThat(jndiBindings.getLength()).isEqualTo(0);
@@ -153,7 +157,9 @@ public class DestroyDataSourceCommandDUnitTest {
       InternalConfigurationPersistenceService ccService =
           internalLocator.getConfigurationPersistenceService();
       Configuration configuration = ccService.getConfiguration("cluster");
-      Document document = XmlUtils.createDocumentFromXml(configuration.getCacheXmlContent());
+      Document document =
+          XmlUtils.createDocumentFromXml(configuration.getCacheXmlContent(),
+              new ServiceLoaderModuleService(LogService.getLogger()));
       NodeList jndiBindings = document.getElementsByTagName("jndi-binding");
 
       AssertionsForClassTypes.assertThat(jndiBindings.getLength()).isEqualTo(0);
diff --git a/geode-connectors/src/main/resources/META-INF/services/org.springframework.shell.core.CommandMarker b/geode-connectors/src/main/resources/META-INF/services/org.apache.geode.management.cli.GeodeCommandMarker
similarity index 100%
rename from geode-connectors/src/main/resources/META-INF/services/org.springframework.shell.core.CommandMarker
rename to geode-connectors/src/main/resources/META-INF/services/org.apache.geode.management.cli.GeodeCommandMarker
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/JdbcConnectorServiceTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/JdbcConnectorServiceTest.java
index baf4b58..64defee 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/JdbcConnectorServiceTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/JdbcConnectorServiceTest.java
@@ -42,6 +42,8 @@ import org.apache.geode.connectors.jdbc.internal.configuration.FieldMapping;
 import org.apache.geode.connectors.jdbc.internal.configuration.RegionMapping;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.cache.extension.ExtensionPoint;
+import org.apache.geode.logging.internal.log4j.api.LogService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 
 public class JdbcConnectorServiceTest {
 
@@ -89,7 +91,7 @@ public class JdbcConnectorServiceTest {
     when(view.isColumnNullable(VALUE_COLUMN_NAME)).thenReturn(true);
 
     service = spy(JdbcConnectorServiceImpl.class);
-    service.init(cache);
+    service.init(cache, new ServiceLoaderModuleService(LogService.getLogger()));
 
     keyColumns.add(KEY_COLUMN_NAME);
     allColumns.add(KEY_COLUMN_NAME);
diff --git a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ConnectionsCommandManagerTest.java b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ConnectionsCommandManagerTest.java
index af64f55..a50ddd5 100644
--- a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ConnectionsCommandManagerTest.java
+++ b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ConnectionsCommandManagerTest.java
@@ -17,19 +17,19 @@ package org.apache.geode.connectors.jdbc.internal.cli;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import java.util.HashSet;
-import java.util.Iterator;
-import java.util.ServiceLoader;
 import java.util.Set;
 
 import org.junit.Before;
 import org.junit.Test;
-import org.springframework.shell.core.CommandMarker;
 
-import org.apache.geode.internal.ClassPathLoader;
+import org.apache.geode.logging.internal.log4j.api.LogService;
+import org.apache.geode.management.cli.GeodeCommandMarker;
 import org.apache.geode.management.cli.GfshCommand;
 import org.apache.geode.management.internal.cli.CommandManager;
 import org.apache.geode.management.internal.cli.commands.VersionCommand;
 import org.apache.geode.management.internal.util.ClasspathScanLoadHelper;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
+import org.apache.geode.services.result.ModuleServiceResult;
 
 /**
  * CommandManagerTest - Includes tests to check the CommandManager functions
@@ -40,7 +40,7 @@ public class ConnectionsCommandManagerTest {
 
   @Before
   public void before() {
-    commandManager = new CommandManager();
+    commandManager = new CommandManager(new ServiceLoaderModuleService(LogService.getLogger()));
   }
 
   /**
@@ -52,26 +52,26 @@ public class ConnectionsCommandManagerTest {
     packagesToScan.add(GfshCommand.class.getPackage().getName());
     packagesToScan.add(VersionCommand.class.getPackage().getName());
 
-    ClasspathScanLoadHelper scanner = new ClasspathScanLoadHelper(packagesToScan);
-    ServiceLoader<CommandMarker> loader =
-        ServiceLoader.load(CommandMarker.class, ClassPathLoader.getLatest().asClassLoader());
-    loader.reload();
-    Iterator<CommandMarker> iterator = loader.iterator();
-
     Set<Class<?>> foundClasses;
 
+    ClasspathScanLoadHelper scanner = new ClasspathScanLoadHelper(packagesToScan);
     // geode's commands
-    foundClasses = scanner.scanPackagesForClassesImplementing(CommandMarker.class,
+    foundClasses = scanner.scanPackagesForClassesImplementing(GeodeCommandMarker.class,
         GfshCommand.class.getPackage().getName(),
         VersionCommand.class.getPackage().getName());
 
-    while (iterator.hasNext()) {
-      foundClasses.add(iterator.next().getClass());
+    ModuleServiceResult<Set<GeodeCommandMarker>> serviceLoadResult =
+        new ServiceLoaderModuleService(LogService.getLogger())
+            .loadService(GeodeCommandMarker.class);
+
+    if (serviceLoadResult.isSuccessful()) {
+      serviceLoadResult.getMessage()
+          .forEach(geodeCommandMarker -> foundClasses.add(geodeCommandMarker.getClass()));
     }
 
     Set<Class<?>> expectedClasses = new HashSet<>();
 
-    for (CommandMarker commandMarker : commandManager.getCommandMarkers()) {
+    for (GeodeCommandMarker commandMarker : commandManager.getCommandMarkers()) {
       expectedClasses.add(commandMarker.getClass());
     }
 
diff --git a/geode-core/build.gradle b/geode-core/build.gradle
index 63ce150..92e7d78 100755
--- a/geode-core/build.gradle
+++ b/geode-core/build.gradle
@@ -185,9 +185,16 @@ dependencies {
     //Commons IO is used in persistence and management
     api('commons-io:commons-io')
 
-    //tools.jar seems to be used by gfsh is some cases to control processes using
-    //the sun attach API? But this code path may not even be used?
-    compileOnly(files("${System.getProperty('java.home')}/../lib/tools.jar"))
+  compileOnly(project(":geode-modules"))
+  api(project(':geode-common-services'))
+  testImplementation(project(":geode-common-services"))
+  integrationTestImplementation(project(":geode-modules"))
+  acceptanceTestImplementation(project(":geode-modules"))
+  distributedTestImplementation(project(":geode-modules"))
+
+  //tools.jar seems to be used by gfsh is some cases to control processes using
+  //the sun attach API? But this code path may not even be used?
+  compileOnly(files("${System.getProperty('java.home')}/../lib/tools.jar"))
 
     //Find bugs is used in multiple places in the code to suppress findbugs warnings
     compileOnly('com.github.stephenc.findbugs:findbugs-annotations')
@@ -343,7 +350,8 @@ dependencies {
     testRuntime('commons-validator:commons-validator')
     testRuntime('com.pholser:junit-quickcheck-generators')
 
-    integrationTestImplementation(project(':geode-gfsh'))
+  integrationTestImplementation(project(":geode-common-services"))
+  integrationTestImplementation(project(':geode-gfsh'))
     integrationTestImplementation(project(':geode-junit')) {
         exclude module: 'geode-core'
     }
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/cache30/CacheXml66DUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/cache30/CacheXml66DUnitTest.java
index 7158532c..5ac4143 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/cache30/CacheXml66DUnitTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/cache30/CacheXml66DUnitTest.java
@@ -134,6 +134,8 @@ import org.apache.geode.internal.cache.xmlcache.RegionAttributesCreation;
 import org.apache.geode.internal.cache.xmlcache.RegionCreation;
 import org.apache.geode.internal.cache.xmlcache.ResourceManagerCreation;
 import org.apache.geode.internal.cache.xmlcache.SerializerCreation;
+import org.apache.geode.logging.internal.log4j.api.LogService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 import org.apache.geode.test.dunit.Assert;
 import org.apache.geode.test.dunit.Host;
 import org.apache.geode.test.dunit.IgnoredException;
@@ -179,7 +181,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
   @Test
   public void testDefaultConnectionPool() throws Exception {
     getSystem();
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     PoolFactory f = cache.createPoolFactory();
     f.addLocator(ALIAS2, 3777);
     f.create("mypool");
@@ -221,7 +223,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testDiskStore() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     DiskStoreFactory dsf = cache.createDiskStoreFactory();
     File[] dirs1 = new File[] {new File("").getAbsoluteFile()};
     DiskStore ds1 =
@@ -264,7 +266,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
   @Test
   public void testExplicitConnectionPool() throws Exception {
     getSystem();
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     PoolFactory f = cache.createPoolFactory();
     f.addServer(ALIAS2, 3777).addServer(ALIAS1, 3888);
     f.setFreeConnectionTimeout(12345).setServerConnectionTimeout(111)
@@ -319,7 +321,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testDiskStoreValidation() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     DiskStoreFactory dsf = cache.createDiskStoreFactory();
     DiskStore ds1 = dsf.create(getUniqueName());
 
@@ -375,7 +377,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testDiskStoreFactory() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     DiskStoreFactory dsf = cache.createDiskStoreFactory();
 
     dsf.setDiskDirs(new File[] {new File("non_exist_dir")});
@@ -416,7 +418,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testRedefineOfDefaultDiskStore() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     DiskStoreFactory dsf = cache.createDiskStoreFactory();
     dsf.setAutoCompact(!DiskStoreFactory.DEFAULT_AUTO_COMPACT);
     DiskStore ds1 = dsf.create(DiskStoreFactory.DEFAULT_DISK_STORE_NAME);
@@ -444,7 +446,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testPersistentPartition() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     attrs.setDataPolicy(DataPolicy.PERSISTENT_PARTITION);
 
@@ -468,7 +470,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testBridgeAttributesRelatedToHAOverFlow65() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     cache.setMessageSyncInterval(3445);
     CacheServer bs = cache.addCacheServer();
     ClientSubscriptionConfig csc = bs.getClientSubscriptionConfig();
@@ -509,7 +511,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testClientSubscriptionQueueUsingDefaultDS() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     cache.setMessageSyncInterval(3445);
     CacheServer bs = cache.addCacheServer();
     ClientSubscriptionConfig csc = bs.getClientSubscriptionConfig();
@@ -543,7 +545,8 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testTransactionWriter() throws Exception {
-    CacheCreation creation = new CacheCreation();
+    CacheCreation creation = new CacheCreation(new ServiceLoaderModuleService(
+        LogService.getLogger()));
     CacheTransactionManagerCreation ctmc = new CacheTransactionManagerCreation();
     ctmc.setWriter(new TestTransactionWriter());
     creation.addCacheTransactionManagerCreation(ctmc);
@@ -628,7 +631,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testBackupFiles() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     File backup1 = new File("/back/me/up");
     File backup2 = new File("/me/too/please");
     cache.addBackup(backup1);
@@ -654,7 +657,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testNormalCache() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     cache.setCopyOnRead(true);
     testXml(cache);
     GemFireCacheImpl c = (GemFireCacheImpl) getCache();
@@ -668,7 +671,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testPARTITION() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionCreation root = (RegionCreation) cache.createRegion("partition", "PARTITION");
     testXml(cache);
     GemFireCacheImpl c = (GemFireCacheImpl) getCache();
@@ -682,7 +685,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testPARTITION_REDUNDANT() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionCreation root = (RegionCreation) cache.createRegion("rpartition", "PARTITION_REDUNDANT");
     testXml(cache);
     GemFireCacheImpl c = (GemFireCacheImpl) getCache();
@@ -696,7 +699,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testPARTITION_PERSISTENT() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionCreation root = (RegionCreation) cache.createRegion("ppartition", "PARTITION_PERSISTENT");
     testXml(cache);
     GemFireCacheImpl c = (GemFireCacheImpl) getCache();
@@ -710,7 +713,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testPARTITION_REDUNDANT_PERSISTENT() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionCreation root =
         (RegionCreation) cache.createRegion("prpartition", "PARTITION_REDUNDANT_PERSISTENT");
     testXml(cache);
@@ -725,7 +728,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testPARTITION_OVERFLOW() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     ResourceManagerCreation rmc = new ResourceManagerCreation();
     rmc.setEvictionHeapPercentage(55.0f);
     rmc.setCriticalHeapPercentage(80.0f);
@@ -748,7 +751,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testPARTITION_REDUNDANT_OVERFLOW() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionCreation root =
         (RegionCreation) cache.createRegion("rpartitionoverflow", "PARTITION_REDUNDANT_OVERFLOW");
     testXml(cache);
@@ -767,7 +770,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testPARTITION_PERSISTENT_OVERFLOW() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     ResourceManagerCreation rmc = new ResourceManagerCreation();
     rmc.setCriticalHeapPercentage(80.0f);
     cache.setResourceManagerCreation(rmc);
@@ -789,7 +792,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testPARTITION_REDUNDANT_PERSISTENT_OVERFLOW() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     ResourceManagerCreation rmc = new ResourceManagerCreation();
     rmc.setEvictionHeapPercentage(0.0f); // test bug 42130
     cache.setResourceManagerCreation(rmc);
@@ -810,7 +813,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testPARTITION_HEAP_LRU() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionCreation root = (RegionCreation) cache.createRegion("partitionlru", "PARTITION_HEAP_LRU");
     testXml(cache);
     GemFireCacheImpl c = (GemFireCacheImpl) getCache();
@@ -827,7 +830,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testPARTITION_REDUNDANT_HEAP_LRU() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionCreation root =
         (RegionCreation) cache.createRegion("rpartitionlru", "PARTITION_REDUNDANT_HEAP_LRU");
     testXml(cache);
@@ -845,7 +848,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testREPLICATE() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionCreation root = (RegionCreation) cache.createRegion("replicate", "REPLICATE");
     testXml(cache);
     GemFireCacheImpl c = (GemFireCacheImpl) getCache();
@@ -858,7 +861,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testREPLICATE_PERSISTENT() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionCreation root = (RegionCreation) cache.createRegion("preplicate", "REPLICATE_PERSISTENT");
     testXml(cache);
     GemFireCacheImpl c = (GemFireCacheImpl) getCache();
@@ -871,7 +874,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testREPLICATE_OVERFLOW() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionCreation root =
         (RegionCreation) cache.createRegion("replicateoverflow", "REPLICATE_OVERFLOW");
     testXml(cache);
@@ -889,7 +892,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testREPLICATE_PERSISTENT_OVERFLOW() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionCreation root =
         (RegionCreation) cache.createRegion("preplicateoverflow", "REPLICATE_PERSISTENT_OVERFLOW");
     testXml(cache);
@@ -907,7 +910,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testREPLICATE_HEAP_LRU() throws Exception, IOException {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionCreation root = (RegionCreation) cache.createRegion("replicatelru", "REPLICATE_HEAP_LRU");
     testXml(cache);
     GemFireCacheImpl c = (GemFireCacheImpl) getCache();
@@ -924,7 +927,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testLOCAL() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionCreation root = (RegionCreation) cache.createRegion("local", "LOCAL");
     testXml(cache);
     GemFireCacheImpl c = (GemFireCacheImpl) getCache();
@@ -937,7 +940,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testLOCAL_PERSISTENT() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionCreation root = (RegionCreation) cache.createRegion("plocal", "LOCAL_PERSISTENT");
     testXml(cache);
     GemFireCacheImpl c = (GemFireCacheImpl) getCache();
@@ -950,7 +953,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testLOCAL_HEAP_LRU() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionCreation root = (RegionCreation) cache.createRegion("locallru", "LOCAL_HEAP_LRU");
     testXml(cache);
     GemFireCacheImpl c = (GemFireCacheImpl) getCache();
@@ -966,7 +969,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testLOCAL_OVERFLOW() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionCreation root = (RegionCreation) cache.createRegion("localoverflow", "LOCAL_OVERFLOW");
     testXml(cache);
     GemFireCacheImpl c = (GemFireCacheImpl) getCache();
@@ -983,7 +986,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testLOCAL_PERSISTENT_OVERFLOW() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionCreation root =
         (RegionCreation) cache.createRegion("cpolocal", "LOCAL_PERSISTENT_OVERFLOW");
     testXml(cache);
@@ -1001,7 +1004,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testPARTITION_PROXY() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionCreation root = (RegionCreation) cache.createRegion("partitionProxy", "PARTITION_PROXY");
     testXml(cache);
     GemFireCacheImpl c = (GemFireCacheImpl) getCache();
@@ -1016,7 +1019,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testPARTITION_PROXY_REDUNDANT() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionCreation root =
         (RegionCreation) cache.createRegion("rpartitionProxy", "PARTITION_PROXY_REDUNDANT");
     testXml(cache);
@@ -1032,7 +1035,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testREPLICATE_PROXY() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionCreation root = (RegionCreation) cache.createRegion("replicateProxy", "REPLICATE_PROXY");
     testXml(cache);
     GemFireCacheImpl c = (GemFireCacheImpl) getCache();
@@ -1206,7 +1209,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
   @Test
   public void testFixedPartitioning() throws Exception {
 
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation();
     FixedPartitionAttributes fpa1 = FixedPartitionAttributes.createFixedPartition("Q1");
     FixedPartitionAttributes fpa2 = FixedPartitionAttributes.createFixedPartition("Q2", true);
@@ -1241,7 +1244,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testFixedPartitioning_colocation_WithAttributes() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     FixedPartitionAttributes fpa1 = FixedPartitionAttributes.createFixedPartition("Q1");
     FixedPartitionAttributes fpa2 = FixedPartitionAttributes.createFixedPartition("Q2", true);
     FixedPartitionAttributes fpa3 = FixedPartitionAttributes.createFixedPartition("Q3", 3);
@@ -1347,7 +1350,8 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testPdxDefaults() throws Exception {
-    CacheCreation creation = new CacheCreation();
+    CacheCreation creation = new CacheCreation(new ServiceLoaderModuleService(
+        LogService.getLogger()));
     testXml(creation);
 
     Cache c = getCache();
@@ -1363,7 +1367,8 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testPdxAttributes() throws Exception {
-    CacheCreation creation = new CacheCreation();
+    CacheCreation creation = new CacheCreation(new ServiceLoaderModuleService(
+        LogService.getLogger()));
     creation.setPdxPersistent(true);
     creation.setPdxReadSerialized(true);
     creation.setPdxIgnoreUnreadFields(true);
@@ -1452,7 +1457,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
   @Test
   public void testTXManagerOnClientCache() throws Exception {
     ClientCacheCreation cc = new ClientCacheCreation();
-    // CacheCreation cc = new CacheCreation();
+    // CacheCreation cc = new CacheCreation(new ServiceLoaderModuleService());
     CacheTransactionManagerCreation txMgrCreation = new CacheTransactionManagerCreation();
     txMgrCreation.addListener(new TestTXListener());
     cc.addCacheTransactionManagerCreation(txMgrCreation);
@@ -1507,7 +1512,8 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
     final String r1 = rNameBase + "1";
 
     // Setting multi-cast via nested region attributes
-    CacheCreation creation = new CacheCreation();
+    CacheCreation creation = new CacheCreation(new ServiceLoaderModuleService(
+        LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(creation);
     attrs.setScope(Scope.LOCAL);
     attrs.setEarlyAck(false);
@@ -1552,7 +1558,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testRecoveryDelayAttributes() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
 
     PartitionAttributesFactory paf = new PartitionAttributesFactory();
@@ -1597,7 +1603,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testDefaultRecoveryDelayAttributes() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
 
     PartitionAttributesFactory paf = new PartitionAttributesFactory();
@@ -1639,7 +1645,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testResourceManagerThresholds() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     final float low = 90.0f;
     final float high = 95.0f;
 
@@ -1789,7 +1795,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testSerializationRegistration() throws Exception {
-    CacheCreation cc = new CacheCreation();
+    CacheCreation cc = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     SerializerCreation sc = new SerializerCreation();
 
     cc.setSerializerCreation(sc);
@@ -1842,7 +1848,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testPartitionedRegionAttributesForCustomPartitioning() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
 
     CacheXMLPartitionResolver partitionResolver = new CacheXMLPartitionResolver();
@@ -1892,7 +1898,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testCacheCreationWithFunctionService() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     FunctionServiceCreation fsc = new FunctionServiceCreation();
     TestFunction function1 = new TestFunction(true, TestFunction.TEST_FUNCTION2);
     TestFunction function2 = new TestFunction(true, TestFunction.TEST_FUNCTION3);
@@ -1919,7 +1925,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testPartitionedRegionAttributesForExpiration() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     attrs.setStatisticsEnabled(true);
     RegionAttributes rootAttrs = null;
@@ -1984,7 +1990,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
   @Test
   public void testPartitionedRegionAttributesForEviction() throws Exception {
     final int redundantCopies = 1;
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     if (getGemFireVersion().equals(CacheXml.VERSION_6_0)) {
       ResourceManagerCreation rm = new ResourceManagerCreation();
       rm.setCriticalHeapPercentage(95);
@@ -2072,7 +2078,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
   @Test
   public void testPartitionedRegionAttributesForCoLocation() throws Exception {
     closeCache();
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation custAttrs = new RegionAttributesCreation(cache);
     RegionAttributesCreation orderAttrs = new RegionAttributesCreation(cache);
     PartitionAttributesFactory custPaf = new PartitionAttributesFactory();
@@ -2122,7 +2128,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
   @Test
   public void testPartitionedRegionAttributesForMemLruWithoutMaxMem() throws Exception {
     final int redundantCopies = 1;
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
 
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     attrs.setStatisticsEnabled(true);
@@ -2162,7 +2168,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
   public void testPartitionedRegionAttributesForMemLruWithMaxMem() throws Exception {
     final int redundantCopies = 1;
     final int maxMem = 25;
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
 
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     attrs.setStatisticsEnabled(true);
@@ -2202,7 +2208,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
   @Test
   public void testReplicatedRegionAttributesForMemLruWithoutMaxMem() throws Exception {
     final int redundantCopies = 1;
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
 
     AttributesFactory fac = new AttributesFactory();
     fac.setDataPolicy(DataPolicy.REPLICATE);
@@ -2230,7 +2236,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
   public void testReplicatedRegionAttributesForMemLruWithMaxMem() throws Exception {
     final int redundantCopies = 1;
     final int maxMem = 25;
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
 
     AttributesFactory fac = new AttributesFactory();
     fac.setDataPolicy(DataPolicy.REPLICATE);
@@ -2258,7 +2264,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testDefaultCacheServerGroups() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     CacheServer bs = cache.addCacheServer();
     bs.setPort(AvailablePortHelper.getRandomAvailableTCPPort());
     bs.setGroups(CacheServer.DEFAULT_GROUPS);
@@ -2272,7 +2278,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testOneCacheServerGroups() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     CacheServer bs = cache.addCacheServer();
     bs.setPort(AvailablePortHelper.getRandomAvailableTCPPort());
     String[] groups = new String[] {"group1"};
@@ -2287,7 +2293,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testTwoCacheServerGroups() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     CacheServer bs = cache.addCacheServer();
     bs.setPort(AvailablePortHelper.getRandomAvailableTCPPort());
     String[] groups = new String[] {"group1", "group2"};
@@ -2302,7 +2308,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testDefaultCacheServerBindAddress() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     CacheServer bs = cache.addCacheServer();
     bs.setPort(AvailablePortHelper.getRandomAvailableTCPPort());
     testXml(cache);
@@ -2315,7 +2321,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testCacheServerBindAddress() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     CacheServer bs = cache.addCacheServer();
     bs.setPort(AvailablePortHelper.getRandomAvailableTCPPort());
     final String BA = ALIAS1;
@@ -2330,7 +2336,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testCacheServerHostnameForClients() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     CacheServer bs = cache.addCacheServer();
     bs.setPort(AvailablePortHelper.getRandomAvailableTCPPort());
     final String BA = ALIAS1;
@@ -2348,7 +2354,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
   @Test
   public void testTwoConnectionPools() throws Exception {
     getSystem();
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     PoolFactory f = cache.createPoolFactory();
     f.addLocator(ALIAS2, 3777).create("mypool");
     f.reset().addLocator(ALIAS1, 3888).create("mypool2");
@@ -2385,7 +2391,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testNoConnectionPools() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     attrs.setPoolName("mypool");
     cache.createVMRegion("rootNORMAL", attrs);
@@ -2408,7 +2414,8 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
     f.setStartDisabled(true).addLocator(ALIAS2, 12345).create("mypool");
     try {
       // now make sure declarative cache can't create the same pool
-      CacheCreation cache = new CacheCreation();
+      CacheCreation cache =
+          new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
       cache.createPoolFactory().addLocator(ALIAS2, 12345).create("mypool");
       IgnoredException expectedException = addIgnoredException(
           String.format("A pool named %s already exists", "mypool"));
@@ -2445,7 +2452,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
         return null;
       }
     });
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     cache.createPoolFactory().addServer(NetworkUtils.getServerHostName(vm0.getHost()), port)
         .setSubscriptionEnabled(true).create("connectionPool");
     cache.setDynamicRegionFactoryConfig(
@@ -2475,7 +2482,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testBridgeAttributesRelatedToHAOverFlow() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     cache.setMessageSyncInterval(3445);
     CacheServer bs = cache.addCacheServer();
     ClientSubscriptionConfig csc = bs.getClientSubscriptionConfig();
@@ -2502,7 +2509,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testBridgeLoadProbe() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     CacheServer server = cache.addCacheServer();
     server.setPort(AvailablePortHelper.getRandomAvailableTCPPort());
     server.setLoadProbe(new MyLoadProbe());
@@ -2516,7 +2523,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testLoadPollInterval() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     CacheServer server = cache.addCacheServer();
     server.setPort(AvailablePortHelper.getRandomAvailableTCPPort());
     server.setLoadPollInterval(12345);
@@ -2621,7 +2628,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testCustomEntryXml() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
 
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     attrs.setScope(Scope.DISTRIBUTED_NO_ACK);
@@ -2666,7 +2673,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testPreloadDataPolicy() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
 
     {
       RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
@@ -2717,7 +2724,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testEnableSubscriptionConflationAttribute() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     attrs.setEnableSubscriptionConflation(true);
     cache.createRegion("root", attrs);
@@ -2806,7 +2813,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testMessageSyncInterval() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     cache.setMessageSyncInterval(123);
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     attrs.setDataPolicy(DataPolicy.NORMAL);
@@ -2823,7 +2830,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testBridgeAttributesRelatedToClientQueuesHA() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     cache.setMessageSyncInterval(3445);
     CacheServer bs = cache.addCacheServer();
     bs.setMaximumMessageCount(12345);
@@ -2851,7 +2858,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testPartitionedRegionInstantiation() {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
 
     PartitionAttributesFactory paf = new PartitionAttributesFactory();
@@ -2866,7 +2873,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testBridgeMaxThreads() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
 
     CacheServer bs = cache.addCacheServer();
     bs.setMaxThreads(37);
@@ -2889,7 +2896,8 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
     final String r3 = rNameBase + "3";
 
     // Setting multi-cast via nested region attributes
-    CacheCreation creation = new CacheCreation();
+    CacheCreation creation = new CacheCreation(new ServiceLoaderModuleService(
+        LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(creation);
     attrs.setScope(Scope.LOCAL);
     attrs.setEarlyAck(false);
@@ -2910,7 +2918,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
     testXml(creation);
 
-    creation = new CacheCreation();
+    creation = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     attrs = new RegionAttributesCreation(creation);
     attrs.setScope(Scope.DISTRIBUTED_ACK);
     attrs.setEarlyAck(false);
@@ -2948,7 +2956,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testRollOplogs() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     // Set properties for Asynch writes
 
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
@@ -2979,7 +2987,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testMaxOplogSize() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     // Set properties for Asynch writes
 
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
@@ -3010,7 +3018,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testDataPolicy() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
 
     {
       RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
@@ -3081,7 +3089,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
     final ResumptionAction[] actions = (ResumptionAction[]) ResumptionAction.VALUES
         .toArray(new ResumptionAction[ResumptionAction.VALUES.size()]);
 
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
 
     // for each policy, try each action and each role...
     for (int policy = 0; policy < policies.length; policy++) {
@@ -3130,7 +3138,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testMultipleCacheListener() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
 
     CacheListener l1 = new MyTestCacheListener();
@@ -3214,7 +3222,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testMultipleTXListener() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     CacheTransactionManagerCreation txMgrCreation = new CacheTransactionManagerCreation();
     TransactionListener l1 = new MyTestTransactionListener();
     TransactionListener l2 = new MySecondTestTransactionListener();
@@ -3275,7 +3283,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testRegisteringNamedRegionAttributes() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs;
 
     String id1 = "id1";
@@ -3370,7 +3378,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testCreateSameRegionTwice() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     String name = "root";
 
@@ -3410,7 +3418,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testCreateSameSubregionTwice() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     String name = getUniqueName();
 
@@ -3474,7 +3482,8 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
     int lockTimeout1 = 345;
     int searchTimeout1 = 567;
 
-    CacheCreation creation = new CacheCreation();
+    CacheCreation creation = new CacheCreation(new ServiceLoaderModuleService(
+        LogService.getLogger()));
     creation.setCopyOnRead(copyOnRead1);
     creation.setIsServer(isServer1);
     creation.setLockLease(lockLease1);
@@ -3496,7 +3505,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
     int lockTimeout2 = 456;
     int searchTimeout2 = 678;
 
-    creation = new CacheCreation();
+    creation = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     creation.setCopyOnRead(copyOnRead2);
     creation.setIsServer(isServer2);
     creation.setLockLease(lockLease2);
@@ -3517,14 +3526,15 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testAddRegionViaCacheXml() throws Exception {
-    CacheCreation creation = new CacheCreation();
+    CacheCreation creation = new CacheCreation(new ServiceLoaderModuleService(
+        LogService.getLogger()));
 
     testXml(creation);
 
     Cache cache = getCache();
     assertTrue(cache.rootRegions().isEmpty());
 
-    creation = new CacheCreation();
+    creation = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
 
     RegionAttributesCreation attrs = new RegionAttributesCreation(creation);
     attrs.setScope(Scope.GLOBAL);
@@ -3555,7 +3565,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
     // Create a subregion of a region that already exists
 
-    creation = new CacheCreation();
+    creation = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     attrs = new RegionAttributesCreation(creation);
     root = creation.createRegion("root", attrs);
 
@@ -3579,7 +3589,8 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testModifyRegionViaCacheXml() throws Exception {
-    CacheCreation creation = new CacheCreation();
+    CacheCreation creation = new CacheCreation(new ServiceLoaderModuleService(
+        LogService.getLogger()));
 
     int timeout1a = 123;
     ExpirationAction action1a = ExpirationAction.LOCAL_DESTROY;
@@ -3608,7 +3619,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
     assertEquals(timeout1b, subregion.getAttributes().getEntryIdleTimeout().getTimeout());
     assertEquals(action1b, subregion.getAttributes().getEntryIdleTimeout().getAction());
 
-    creation = new CacheCreation();
+    creation = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
 
     int timeout2a = 234;
     ExpirationAction action2a = ExpirationAction.LOCAL_INVALIDATE;
@@ -3647,7 +3658,8 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
     String key1 = "KEY1";
     String value1 = "VALUE1";
 
-    CacheCreation creation = new CacheCreation();
+    CacheCreation creation = new CacheCreation(new ServiceLoaderModuleService(
+        LogService.getLogger()));
 
     RegionAttributesCreation attrs = new RegionAttributesCreation(creation);
     attrs.setScope(Scope.LOCAL);
@@ -3662,7 +3674,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
     assertEquals(1, root.entrySet(false).size());
     assertEquals(value1, root.get(key1));
 
-    creation = new CacheCreation();
+    creation = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
 
     attrs = new RegionAttributesCreation(creation);
     attrs.setScope(Scope.LOCAL);
@@ -3690,7 +3702,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testEnableBridgeConflationAttribute() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     attrs.setEnableBridgeConflation(true);
     cache.createRegion("root", attrs);
@@ -3705,7 +3717,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testEnableAsyncConflationAttribute() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     attrs.setEnableAsyncConflation(true);
     cache.createRegion("root", attrs);
@@ -3718,7 +3730,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testDynamicRegionFactoryDefault() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     cache.setDynamicRegionFactoryConfig(new DynamicRegionFactory.Config());
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     cache.createRegion("root", attrs);
@@ -3737,7 +3749,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
 
   @Test
   public void testDynamicRegionFactoryNonDefault() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     cache.setDynamicRegionFactoryConfig(
         new DynamicRegionFactory.Config((File) null, null, false, false));
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
@@ -3760,7 +3772,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testDynamicRegionFactoryDiskDir() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     File f = new File("diskDir");
     f.mkdirs();
     cache.setDynamicRegionFactoryConfig(new DynamicRegionFactory.Config(f, null, true, true));
@@ -3784,7 +3796,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testServer() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     cache.setIsServer(true);
     assertTrue(cache.isServer());
 
@@ -3798,7 +3810,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testBridgeServers() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
 
     CacheServer bridge1 = cache.addCacheServer();
     setBridgeAttributes(bridge1);
@@ -3814,7 +3826,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testIsLockGrantorAttribute() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
 
     attrs.setLockGrantor(true);
@@ -3834,7 +3846,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testTransactionListener() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     CacheTransactionManagerCreation txMgrCreation = new CacheTransactionManagerCreation();
     txMgrCreation.setListener(new MyTestTransactionListener());
     cache.addCacheTransactionManagerCreation(txMgrCreation);
@@ -3848,7 +3860,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testCacheTransactionManager() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     CacheTransactionManagerCreation txMgrCreation = new CacheTransactionManagerCreation();
     cache.addCacheTransactionManagerCreation(txMgrCreation);
     testXml(cache);
@@ -3861,7 +3873,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testConstrainedValues() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     attrs.setValueConstraint(String.class);
 
@@ -3925,7 +3937,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testDefaultCache() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
 
     testXml(cache);
   }
@@ -3935,7 +3947,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testNonDefaultCache() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     cache.setLockTimeout(42);
     cache.setLockLease(43);
     cache.setSearchTimeout(44);
@@ -3952,7 +3964,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testEntriesInRootRegion() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionCreation root =
         (RegionCreation) cache.createRegion("root", new RegionAttributesCreation(cache));
     root.put("KEY1", "VALUE1");
@@ -3967,7 +3979,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testConstrainedKeys() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     attrs.setKeyConstraint(String.class);
     cache.createRegion("root", attrs);
@@ -3980,7 +3992,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testExpirationAttriubutes() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     attrs.setStatisticsEnabled(true);
 
@@ -4014,7 +4026,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testCacheLoaderWithDeclarables() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
 
     CacheLoaderWithDeclarables loader = new CacheLoaderWithDeclarables();
@@ -4030,7 +4042,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testCacheWriter() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
 
     CacheWriter writer = new MyTestCacheWriter();
@@ -4046,7 +4058,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testCacheListener() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
 
     CacheListener listener = new MyTestCacheListener();
@@ -4062,7 +4074,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testNonDefaultRegionAttributes() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
 
     attrs.setScope(Scope.DISTRIBUTED_NO_ACK);
@@ -4239,7 +4251,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testNestedRegions() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
 
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     attrs.setScope(Scope.DISTRIBUTED_NO_ACK);
@@ -4291,7 +4303,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testDiskDirs() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
 
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     File[] dirs = new File[] {new File(getUniqueName() + "-dir1"),
@@ -4314,7 +4326,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testOverflowAndBackup() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
 
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     attrs.setMirrorType(MirrorType.KEYS_VALUES);
@@ -4330,7 +4342,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
    */
   @Test
   public void testDiskWriteAttributes() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     // Set properties for Asynch writes
 
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
@@ -4387,7 +4399,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
         LogWriterUtils.getLogWriter().info("Parsing " + xmlFile);
 
         FileInputStream fis = new FileInputStream(xmlFile);
-        CacheXmlParser.parse(fis);
+        CacheXmlParser.parse(fis, new ServiceLoaderModuleService(LogService.getLogger()));
       }
 
     } else {
@@ -4395,24 +4407,24 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
       File example = new File(createTempFileFromResource(getClass(),
           "/org/apache/geode/cache/doc-files/example-cache.xml").getAbsolutePath());
       FileInputStream fis = new FileInputStream(example);
-      CacheXmlParser.parse(fis);
+      CacheXmlParser.parse(fis, new ServiceLoaderModuleService(LogService.getLogger()));
 
       File example2 = new File(createTempFileFromResource(getClass(),
           "/org/apache/geode/cache/doc-files/example2-cache.xml").getAbsolutePath());
       fis = new FileInputStream(example2);
-      CacheXmlParser.parse(fis);
+      CacheXmlParser.parse(fis, new ServiceLoaderModuleService(LogService.getLogger()));
 
       File example3 = new File(createTempFileFromResource(getClass(),
           "/org/apache/geode/cache/doc-files/example3-cache.xml").getAbsolutePath());
       fis = new FileInputStream(example3);
-      CacheXmlParser.parse(fis);
+      CacheXmlParser.parse(fis, new ServiceLoaderModuleService(LogService.getLogger()));
     }
   }
 
   @Test
   public void testEvictionLRUEntryAttributes() throws Exception {
     final String rName = getUniqueName();
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     attrs.setEvictionAttributes(
         EvictionAttributes.createLRUEntryAttributes(80, EvictionAction.LOCAL_DESTROY));
@@ -4461,7 +4473,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
   @Test
   public void testEvictionLRUMemoryAttributes() throws Exception {
     final String rName = getUniqueName();
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     attrs.setEvictionAttributes(
         EvictionAttributes.createLRUMemoryAttributes(10, new EvictionObjectSizer()));
@@ -4472,7 +4484,7 @@ public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {
   @Test
   public void testEvictionLRUHeapAttributes() throws Exception {
     final String rName = getUniqueName();
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     attrs.setEvictionAttributes(EvictionAttributes
         .createLRUHeapAttributes(new EvictionObjectSizer(), EvictionAction.LOCAL_DESTROY));
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/cache30/CacheXml70DUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/cache30/CacheXml70DUnitTest.java
index 1b6cbb8..02231ab 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/cache30/CacheXml70DUnitTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/cache30/CacheXml70DUnitTest.java
@@ -41,6 +41,8 @@ import org.apache.geode.internal.cache.xmlcache.AsyncEventQueueCreation;
 import org.apache.geode.internal.cache.xmlcache.CacheCreation;
 import org.apache.geode.internal.cache.xmlcache.CacheXml;
 import org.apache.geode.internal.cache.xmlcache.RegionAttributesCreation;
+import org.apache.geode.logging.internal.log4j.api.LogService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 
 
 public class CacheXml70DUnitTest extends CacheXml66DUnitTest {
@@ -53,7 +55,7 @@ public class CacheXml70DUnitTest extends CacheXml66DUnitTest {
   /** make sure we can create regions with concurrencyChecksEnabled=true */
   @Test
   public void testConcurrencyChecksEnabled() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     attrs.setScope(Scope.DISTRIBUTED_ACK);
     attrs.setDataPolicy(DataPolicy.REPLICATE);
@@ -108,7 +110,7 @@ public class CacheXml70DUnitTest extends CacheXml66DUnitTest {
 
   @Test
   public void testGatewayConflictResolver() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     cache.setGatewayConflictResolver(new MyGatewayConflictResolver());
     testXml(cache);
     Cache c = getCache();
@@ -121,7 +123,7 @@ public class CacheXml70DUnitTest extends CacheXml66DUnitTest {
   @Test
   public void testAsyncEventQueue() throws Exception {
     getSystem();
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
 
     String id = "WBCLChannel";
     AsyncEventQueueFactory factory = cache.createAsyncEventQueueFactory();
@@ -156,7 +158,7 @@ public class CacheXml70DUnitTest extends CacheXml66DUnitTest {
   @Test
   public void testConcurrentAsyncEventQueue() throws Exception {
     getSystem();
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
 
     String id = "WBCLChannel";
     AsyncEventQueueFactory factory = cache.createAsyncEventQueueFactory();
@@ -194,7 +196,7 @@ public class CacheXml70DUnitTest extends CacheXml66DUnitTest {
   @Test
   public void testAsyncEventQueueWithGatewayEventFilter() throws Exception {
     getSystem();
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
 
     String id = "WBCLChannel";
     AsyncEventQueueFactory factory = cache.createAsyncEventQueueFactory();
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/cache30/CacheXml80DUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/cache30/CacheXml80DUnitTest.java
index 78a3975..a8fc95f 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/cache30/CacheXml80DUnitTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/cache30/CacheXml80DUnitTest.java
@@ -48,6 +48,8 @@ import org.apache.geode.internal.cache.xmlcache.CacheXml;
 import org.apache.geode.internal.cache.xmlcache.CacheXmlGenerator;
 import org.apache.geode.internal.cache.xmlcache.DiskStoreAttributesCreation;
 import org.apache.geode.internal.cache.xmlcache.RegionAttributesCreation;
+import org.apache.geode.logging.internal.log4j.api.LogService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 
 
 @SuppressWarnings("serial")
@@ -62,7 +64,8 @@ public class CacheXml80DUnitTest extends CacheXml70DUnitTest {
   public void testCompressor() throws Exception {
     final String regionName = "testCompressor";
 
-    final CacheCreation cache = new CacheCreation();
+    final CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(
+        LogService.getLogger()));
     final RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     attrs.setCompressor(SnappyCompressor.getDefaultInstance());
     /* Region regionBefore = */ cache.createRegion(regionName, attrs);
@@ -86,7 +89,7 @@ public class CacheXml80DUnitTest extends CacheXml70DUnitTest {
    */
   @Test
   public void testIndexXmlCreation() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     attrs.setScope(Scope.DISTRIBUTED_ACK);
     attrs.setDataPolicy(DataPolicy.REPLICATE);
@@ -182,7 +185,7 @@ public class CacheXml80DUnitTest extends CacheXml70DUnitTest {
 
   @Test
   public void testCacheServerDisableTcpNoDelay() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
 
     CacheServer cs = cache.addCacheServer();
     cs.setPort(0);
@@ -195,7 +198,7 @@ public class CacheXml80DUnitTest extends CacheXml70DUnitTest {
 
   @Test
   public void testCacheServerEnableTcpNoDelay() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
 
     CacheServer cs = cache.addCacheServer();
     cs.setPort(0);
@@ -208,7 +211,7 @@ public class CacheXml80DUnitTest extends CacheXml70DUnitTest {
 
   @Test
   public void testDiskUsage() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
 
     DiskStoreAttributesCreation disk = new DiskStoreAttributesCreation();
     disk.setDiskUsageWarningPercentage(97);
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/cache30/CacheXml81DUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/cache30/CacheXml81DUnitTest.java
index 631395e..4fba94c 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/cache30/CacheXml81DUnitTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/cache30/CacheXml81DUnitTest.java
@@ -33,6 +33,8 @@ import org.apache.geode.internal.cache.xmlcache.CacheCreation;
 import org.apache.geode.internal.cache.xmlcache.CacheXml;
 import org.apache.geode.internal.cache.xmlcache.RegionAttributesCreation;
 import org.apache.geode.internal.cache.xmlcache.XmlParser;
+import org.apache.geode.logging.internal.log4j.api.LogService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 import org.apache.geode.test.dunit.IgnoredException;
 
 /**
@@ -62,7 +64,8 @@ public class CacheXml81DUnitTest extends CacheXml80DUnitTest {
    */
   @Test
   public void testCacheExtension() throws Exception {
-    final CacheCreation cache = new CacheCreation();
+    final CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(
+        LogService.getLogger()));
     final MockCacheExtension extension = new MockCacheExtension("testCacheExtension");
     cache.getExtensionPoint().addExtension(extension);
 
@@ -95,7 +98,8 @@ public class CacheXml81DUnitTest extends CacheXml80DUnitTest {
   @Test
   public void testRegionExtension() throws Exception {
     final String regionName = "testRegionExtension";
-    final CacheCreation cache = new CacheCreation();
+    final CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(
+        LogService.getLogger()));
     final RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     Extensible<Region<?, ?>> region =
         (Extensible<Region<?, ?>>) cache.createRegion(regionName, attrs);
@@ -133,7 +137,8 @@ public class CacheXml81DUnitTest extends CacheXml80DUnitTest {
   @Test
   public void testLocatorInException() throws Exception {
     final String regionName = "testRegionExtension";
-    final CacheCreation cache = new CacheCreation();
+    final CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(
+        LogService.getLogger()));
     final RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     Extensible<Region<?, ?>> region =
         (Extensible<Region<?, ?>>) cache.createRegion(regionName, attrs);
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/cache30/CacheXmlGeode10DUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/cache30/CacheXmlGeode10DUnitTest.java
index 72c9b05..c02c06e 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/cache30/CacheXmlGeode10DUnitTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/cache30/CacheXmlGeode10DUnitTest.java
@@ -47,6 +47,8 @@ import org.apache.geode.internal.cache.xmlcache.CacheXml;
 import org.apache.geode.internal.cache.xmlcache.Declarable2;
 import org.apache.geode.internal.cache.xmlcache.RegionAttributesCreation;
 import org.apache.geode.internal.cache.xmlcache.ResourceManagerCreation;
+import org.apache.geode.logging.internal.log4j.api.LogService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 import org.apache.geode.test.dunit.IgnoredException;
 import org.apache.geode.util.internal.GeodeGlossary;
 
@@ -65,7 +67,8 @@ public class CacheXmlGeode10DUnitTest extends CacheXml81DUnitTest {
 
     final String regionName = "testEnableOffHeapMemory";
 
-    final CacheCreation cache = new CacheCreation();
+    final CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(
+        LogService.getLogger()));
     final RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     attrs.setOffHeap(true);
     assertEquals(true, attrs.getOffHeap());
@@ -92,7 +95,8 @@ public class CacheXmlGeode10DUnitTest extends CacheXml81DUnitTest {
       throws Exception {
     final String regionName = getUniqueName();
 
-    final CacheCreation cache = new CacheCreation();
+    final CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(
+        LogService.getLogger()));
     final RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
     attrs.setOffHeap(true);
     assertEquals(true, attrs.getOffHeap());
@@ -126,7 +130,8 @@ public class CacheXmlGeode10DUnitTest extends CacheXml81DUnitTest {
     final String rootRegionName = getUniqueName();
     final String subRegionName = "subRegion";
 
-    final CacheCreation cache = new CacheCreation();
+    final CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(
+        LogService.getLogger()));
     final RegionAttributesCreation rootRegionAttrs = new RegionAttributesCreation(cache);
     assertEquals(false, rootRegionAttrs.getOffHeap());
 
@@ -167,7 +172,7 @@ public class CacheXmlGeode10DUnitTest extends CacheXml81DUnitTest {
   @Override
   @Test
   public void testResourceManagerThresholds() throws Exception {
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     final float low = 90.0f;
     final float high = 95.0f;
 
@@ -257,7 +262,8 @@ public class CacheXmlGeode10DUnitTest extends CacheXml81DUnitTest {
     final String regionName = this.testName.getMethodName();
 
     // Create AsyncEventQueue with Listener
-    final CacheCreation cache = new CacheCreation();
+    final CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(
+        LogService.getLogger()));
     AsyncEventQueueFactory factory = cache.createAsyncEventQueueFactory();
 
     AsyncEventListener listener = new MyAsyncEventListenerGeode10();
@@ -308,7 +314,7 @@ public class CacheXmlGeode10DUnitTest extends CacheXml81DUnitTest {
   @Test
   public void testPoolSocketFactory() throws IOException {
     getSystem();
-    CacheCreation cache = new CacheCreation();
+    CacheCreation cache = new CacheCreation(new ServiceLoaderModuleService(LogService.getLogger()));
     PoolFactory f = cache.createPoolFactory();
     f.setSocketFactory(new TestSocketFactory());
     f.addServer("localhost", 443);
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/cache30/ReconnectWithClusterConfigurationDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/cache30/ReconnectWithClusterConfigurationDUnitTest.java
index 1c8f92c..1dbd399 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/cache30/ReconnectWithClusterConfigurationDUnitTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/cache30/ReconnectWithClusterConfigurationDUnitTest.java
@@ -52,6 +52,8 @@ import org.apache.geode.distributed.internal.membership.api.MembershipManagerHel
 import org.apache.geode.internal.AvailablePort;
 import org.apache.geode.internal.AvailablePortHelper;
 import org.apache.geode.internal.inet.LocalHostUtil;
+import org.apache.geode.logging.internal.log4j.api.LogService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 import org.apache.geode.test.awaitility.GeodeAwaitility;
 import org.apache.geode.test.dunit.Assert;
 import org.apache.geode.test.dunit.AsyncInvocation;
@@ -98,7 +100,8 @@ public class ReconnectWithClusterConfigurationDUnitTest implements Serializable
           Properties props = getDistributedSystemProperties();
           locator = InternalLocator.startLocator(locatorPorts[locatorNumber], new File(""),
               null, null, LocalHostUtil.getLocalHost(), true,
-              props, null, Paths.get(workingDir));
+              props, null, Paths.get(workingDir), new ServiceLoaderModuleService(
+                  LogService.getLogger()));
           system = locator.getDistributedSystem();
           cache = ((InternalLocator) locator).getCache();
           IgnoredException.addIgnoredException(
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/distributed/internal/ClusterDistributionManagerDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/distributed/internal/ClusterDistributionManagerDUnitTest.java
index 9d3bbd9..93d1b2c 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/distributed/internal/ClusterDistributionManagerDUnitTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/distributed/internal/ClusterDistributionManagerDUnitTest.java
@@ -73,6 +73,7 @@ import org.apache.geode.distributed.internal.membership.api.MembershipManagerHel
 import org.apache.geode.distributed.internal.membership.api.MembershipView;
 import org.apache.geode.distributed.internal.membership.gms.GMSMembership;
 import org.apache.geode.logging.internal.log4j.api.LogService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 import org.apache.geode.test.dunit.Invoke;
 import org.apache.geode.test.dunit.SerializableRunnable;
 import org.apache.geode.test.dunit.VM;
@@ -434,7 +435,9 @@ public class ClusterDistributionManagerDUnitTest extends CacheTestCase {
   private void createAlertListener() throws Exception {
     DistributedSystemConfig config =
         AdminDistributedSystemFactory.defineDistributedSystem(getSystemStatic(), null);
-    AdminDistributedSystem adminSystem = AdminDistributedSystemFactory.getDistributedSystem(config);
+    AdminDistributedSystem adminSystem =
+        AdminDistributedSystemFactory.getDistributedSystem(config,
+            new ServiceLoaderModuleService(LogService.getLogger()));
     adminSystem.setAlertLevel(AlertLevel.SEVERE);
     adminSystem.addAlertListener(alert -> {
       try {
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/AlterMockCacheExtensionFunction.java b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/AlterMockCacheExtensionFunction.java
index 275e07d..6f2cb61 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/AlterMockCacheExtensionFunction.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/AlterMockCacheExtensionFunction.java
@@ -37,6 +37,7 @@ import org.apache.geode.management.internal.cli.CliUtil;
 import org.apache.geode.management.internal.configuration.domain.XmlEntity;
 import org.apache.geode.management.internal.functions.CliFunctionResult;
 import org.apache.geode.management.internal.i18n.CliStrings;
+import org.apache.geode.services.module.ModuleService;
 
 /**
  * Function to create {@link MockCacheExtension} on a {@link Region}.
@@ -48,7 +49,11 @@ public class AlterMockCacheExtensionFunction implements Function, DataSerializab
 
   private static final long serialVersionUID = 1L;
 
-  public static final Function INSTANCE = new AlterMockCacheExtensionFunction();
+  private final ModuleService moduleService;
+
+  public AlterMockCacheExtensionFunction(ModuleService moduleService) {
+    this.moduleService = moduleService;
+  }
 
   @Override
   public void execute(FunctionContext context) {
@@ -69,7 +74,8 @@ public class AlterMockCacheExtensionFunction implements Function, DataSerializab
     }
 
     final XmlEntity xmlEntity =
-        XmlEntity.builder().withType(ELEMENT_CACHE).withNamespace(PREFIX, NAMESPACE).build();
+        XmlEntity.builder().withType(ELEMENT_CACHE).withNamespace(PREFIX, NAMESPACE)
+            .build(moduleService);
 
     final ResultSender<Object> resultSender = context.getResultSender();
     final String memberNameOrId =
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/AlterMockRegionExtensionFunction.java b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/AlterMockRegionExtensionFunction.java
index 74b9edf..ecdfd2f 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/AlterMockRegionExtensionFunction.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/AlterMockRegionExtensionFunction.java
@@ -34,6 +34,7 @@ import org.apache.geode.management.internal.cli.CliUtil;
 import org.apache.geode.management.internal.configuration.domain.XmlEntity;
 import org.apache.geode.management.internal.functions.CliFunctionResult;
 import org.apache.geode.management.internal.i18n.CliStrings;
+import org.apache.geode.services.module.ModuleService;
 
 /**
  * Function to alter {@link MockRegionExtension} on a {@link Region}.
@@ -57,7 +58,11 @@ public class AlterMockRegionExtensionFunction implements Function, DataSerializa
 
   private static final long serialVersionUID = 1L;
 
-  public static final Function INSTANCE = new AlterMockRegionExtensionFunction();
+  private final ModuleService moduleService;
+
+  public AlterMockRegionExtensionFunction(ModuleService moduleService) {
+    this.moduleService = moduleService;
+  }
 
   @Override
   public void execute(FunctionContext context) {
@@ -78,7 +83,8 @@ public class AlterMockRegionExtensionFunction implements Function, DataSerializa
       }
     }
 
-    XmlEntity xmlEntity = new XmlEntity(CacheXml.REGION, "name", region.getName());
+    XmlEntity xmlEntity =
+        new XmlEntity(CacheXml.REGION, "name", region.getName(), moduleService);
 
     final ResultSender<Object> resultSender = context.getResultSender();
     final String memberNameOrId =
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/CreateMockCacheExtensionFunction.java b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/CreateMockCacheExtensionFunction.java
index 48149d0..78ef687 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/CreateMockCacheExtensionFunction.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/CreateMockCacheExtensionFunction.java
@@ -36,6 +36,7 @@ import org.apache.geode.management.internal.cli.CliUtil;
 import org.apache.geode.management.internal.configuration.domain.XmlEntity;
 import org.apache.geode.management.internal.functions.CliFunctionResult;
 import org.apache.geode.management.internal.i18n.CliStrings;
+import org.apache.geode.services.module.ModuleService;
 
 /**
  * Function to create {@link MockCacheExtension} on a {@link Region}.
@@ -47,7 +48,11 @@ public class CreateMockCacheExtensionFunction implements Function, DataSerializa
 
   private static final long serialVersionUID = 1L;
 
-  public static final Function INSTANCE = new CreateMockCacheExtensionFunction();
+  private final ModuleService moduleService;
+
+  public CreateMockCacheExtensionFunction(ModuleService moduleService) {
+    this.moduleService = moduleService;
+  }
 
   @Override
   public void execute(FunctionContext context) {
@@ -66,7 +71,8 @@ public class CreateMockCacheExtensionFunction implements Function, DataSerializa
     extension.onCreate(extensible, extensible);
 
     final XmlEntity xmlEntity =
-        XmlEntity.builder().withType(ELEMENT_CACHE).withNamespace(PREFIX, NAMESPACE).build();
+        XmlEntity.builder().withType(ELEMENT_CACHE).withNamespace(PREFIX, NAMESPACE)
+            .build(moduleService);
 
     final ResultSender<Object> resultSender = context.getResultSender();
     final String memberNameOrId =
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/CreateMockRegionExtensionFunction.java b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/CreateMockRegionExtensionFunction.java
index 8fe2622..adb31b3 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/CreateMockRegionExtensionFunction.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/CreateMockRegionExtensionFunction.java
@@ -33,6 +33,7 @@ import org.apache.geode.management.internal.cli.CliUtil;
 import org.apache.geode.management.internal.configuration.domain.XmlEntity;
 import org.apache.geode.management.internal.functions.CliFunctionResult;
 import org.apache.geode.management.internal.i18n.CliStrings;
+import org.apache.geode.services.module.ModuleService;
 
 /**
  * Function to create {@link MockRegionExtension} on a {@link Region}.
@@ -56,7 +57,11 @@ public class CreateMockRegionExtensionFunction implements Function, DataSerializ
 
   private static final long serialVersionUID = 1L;
 
-  public static final Function INSTANCE = new CreateMockRegionExtensionFunction();
+  private final ModuleService moduleService;
+
+  public CreateMockRegionExtensionFunction(ModuleService moduleService) {
+    this.moduleService = moduleService;
+  }
 
   @Override
   public void execute(FunctionContext context) {
@@ -75,7 +80,8 @@ public class CreateMockRegionExtensionFunction implements Function, DataSerializ
     extension.beforeCreate(extensible, cache);
     extension.onCreate(extensible, extensible);
 
-    XmlEntity xmlEntity = new XmlEntity(CacheXml.REGION, "name", region.getName());
+    XmlEntity xmlEntity =
+        new XmlEntity(CacheXml.REGION, "name", region.getName(), moduleService);
 
     final ResultSender<Object> resultSender = context.getResultSender();
     final String memberNameOrId =
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/DestroyMockCacheExtensionFunction.java b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/DestroyMockCacheExtensionFunction.java
index 2cd12d6..f7acd88 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/DestroyMockCacheExtensionFunction.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/DestroyMockCacheExtensionFunction.java
@@ -37,6 +37,7 @@ import org.apache.geode.management.internal.cli.CliUtil;
 import org.apache.geode.management.internal.configuration.domain.XmlEntity;
 import org.apache.geode.management.internal.functions.CliFunctionResult;
 import org.apache.geode.management.internal.i18n.CliStrings;
+import org.apache.geode.services.module.ModuleService;
 
 /**
  * Function to create {@link MockCacheExtension} on a {@link Region}.
@@ -48,7 +49,11 @@ public class DestroyMockCacheExtensionFunction implements Function, DataSerializ
 
   private static final long serialVersionUID = 1L;
 
-  public static final Function INSTANCE = new DestroyMockCacheExtensionFunction();
+  private final ModuleService moduleService;
+
+  public DestroyMockCacheExtensionFunction(ModuleService moduleService) {
+    this.moduleService = moduleService;
+  }
 
   @Override
   public void execute(FunctionContext context) {
@@ -68,7 +73,8 @@ public class DestroyMockCacheExtensionFunction implements Function, DataSerializ
     }
 
     final XmlEntity xmlEntity =
-        XmlEntity.builder().withType(ELEMENT_CACHE).withNamespace(PREFIX, NAMESPACE).build();
+        XmlEntity.builder().withType(ELEMENT_CACHE).withNamespace(PREFIX, NAMESPACE)
+            .build(moduleService);
 
     final ResultSender<Object> resultSender = context.getResultSender();
     final String memberNameOrId =
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/DestroyMockRegionExtensionFunction.java b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/DestroyMockRegionExtensionFunction.java
index 9b25fca..67e2fa2 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/DestroyMockRegionExtensionFunction.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/DestroyMockRegionExtensionFunction.java
@@ -34,6 +34,7 @@ import org.apache.geode.management.internal.cli.CliUtil;
 import org.apache.geode.management.internal.configuration.domain.XmlEntity;
 import org.apache.geode.management.internal.functions.CliFunctionResult;
 import org.apache.geode.management.internal.i18n.CliStrings;
+import org.apache.geode.services.module.ModuleService;
 
 /**
  * Function to destroy {@link MockRegionExtension} on a {@link Region}.
@@ -54,7 +55,12 @@ import org.apache.geode.management.internal.i18n.CliStrings;
 public class DestroyMockRegionExtensionFunction implements Function, DataSerializable {
 
   private static final long serialVersionUID = 1L;
-  public static final Function INSTANCE = new DestroyMockRegionExtensionFunction();
+
+  private final ModuleService moduleService;
+
+  public DestroyMockRegionExtensionFunction(ModuleService moduleService) {
+    this.moduleService = moduleService;
+  }
 
   @Override
   public void execute(FunctionContext context) {
@@ -74,7 +80,8 @@ public class DestroyMockRegionExtensionFunction implements Function, DataSeriali
       }
     }
 
-    XmlEntity xmlEntity = new XmlEntity(CacheXml.REGION, "name", region.getName());
+    XmlEntity xmlEntity =
+        new XmlEntity(CacheXml.REGION, "name", region.getName(), moduleService);
 
     final ResultSender<Object> resultSender = context.getResultSender();
     final String memberNameOrId =
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/MockExtensionCommands.java b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/MockExtensionCommands.java
index 1a32484..8414eb5 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/MockExtensionCommands.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/extension/mock/MockExtensionCommands.java
@@ -18,7 +18,6 @@ package org.apache.geode.internal.cache.extension.mock;
 import java.util.List;
 import java.util.Set;
 
-import org.springframework.shell.core.CommandMarker;
 import org.springframework.shell.core.annotation.CliCommand;
 import org.springframework.shell.core.annotation.CliOption;
 
@@ -30,6 +29,7 @@ import org.apache.geode.distributed.internal.InternalConfigurationPersistenceSer
 import org.apache.geode.distributed.internal.InternalLocator;
 import org.apache.geode.internal.cache.GemFireCacheImpl;
 import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.management.cli.GeodeCommandMarker;
 import org.apache.geode.management.cli.Result;
 import org.apache.geode.management.internal.cli.result.CommandResult;
 import org.apache.geode.management.internal.cli.result.model.ResultModel;
@@ -39,13 +39,14 @@ import org.apache.geode.management.internal.security.ResourceOperation;
 import org.apache.geode.management.internal.util.ManagementUtils;
 import org.apache.geode.security.ResourcePermission.Operation;
 import org.apache.geode.security.ResourcePermission.Resource;
+import org.apache.geode.services.module.ModuleService;
 
 /**
  * Mock Extension gfsh commands.
  *
  * @since GemFire 8.1
  */
-public class MockExtensionCommands implements CommandMarker {
+public class MockExtensionCommands implements GeodeCommandMarker {
 
   public static final String OPTION_VALUE = "value";
 
@@ -63,6 +64,8 @@ public class MockExtensionCommands implements CommandMarker {
 
   public static final String DESTROY_MOCK_CACHE_EXTENSION = "destroy mock cache extension";
 
+  private ModuleService moduleService;
+
   /**
    * Creates a {@link MockRegionExtension} on the given <code>regionName</code>.
    *
@@ -77,7 +80,7 @@ public class MockExtensionCommands implements CommandMarker {
       @CliOption(key = OPTION_REGION_NAME, mandatory = true) final String regionName,
       @CliOption(key = OPTION_VALUE, mandatory = true) final String value) {
     return executeFunctionOnAllMembersTabulateResultPersist(
-        CreateMockRegionExtensionFunction.INSTANCE, true,
+        new CreateMockRegionExtensionFunction(moduleService), true,
         CreateMockRegionExtensionFunction.toArgs(regionName, value));
   }
 
@@ -95,7 +98,7 @@ public class MockExtensionCommands implements CommandMarker {
       @CliOption(key = OPTION_REGION_NAME, mandatory = true) final String regionName,
       @CliOption(key = OPTION_VALUE, mandatory = true) final String value) {
     return executeFunctionOnAllMembersTabulateResultPersist(
-        AlterMockRegionExtensionFunction.INSTANCE, true,
+        new AlterMockRegionExtensionFunction(moduleService), true,
         AlterMockRegionExtensionFunction.toArgs(regionName, value));
   }
 
@@ -111,7 +114,7 @@ public class MockExtensionCommands implements CommandMarker {
   public Result destroyMockRegionExtension(
       @CliOption(key = OPTION_REGION_NAME, mandatory = true) final String regionName) {
     return executeFunctionOnAllMembersTabulateResultPersist(
-        DestroyMockRegionExtensionFunction.INSTANCE, true,
+        new DestroyMockRegionExtensionFunction(moduleService), true,
         DestroyMockRegionExtensionFunction.toArgs(regionName));
   }
 
@@ -127,7 +130,7 @@ public class MockExtensionCommands implements CommandMarker {
   public Result createMockCacheExtension(
       @CliOption(key = OPTION_VALUE, mandatory = true) final String value) {
     return executeFunctionOnAllMembersTabulateResultPersist(
-        CreateMockCacheExtensionFunction.INSTANCE, true,
+        new CreateMockCacheExtensionFunction(moduleService), true,
         CreateMockCacheExtensionFunction.toArgs(value));
   }
 
@@ -143,7 +146,7 @@ public class MockExtensionCommands implements CommandMarker {
   public Result alterMockCacheExtension(
       @CliOption(key = OPTION_VALUE, mandatory = true) final String value) {
     return executeFunctionOnAllMembersTabulateResultPersist(
-        AlterMockCacheExtensionFunction.INSTANCE, true,
+        new AlterMockCacheExtensionFunction(moduleService), true,
         AlterMockCacheExtensionFunction.toArgs(value));
   }
 
@@ -157,7 +160,7 @@ public class MockExtensionCommands implements CommandMarker {
   @ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ)
   public Result destroyMockCacheExtension() {
     return executeFunctionOnAllMembersTabulateResultPersist(
-        DestroyMockCacheExtensionFunction.INSTANCE, false);
+        new DestroyMockCacheExtensionFunction(moduleService), false);
   }
 
   /**
@@ -201,4 +204,8 @@ public class MockExtensionCommands implements CommandMarker {
     return new CommandResult(resultModel);
   }
 
+  @Override
+  public void init(ModuleService moduleService) {
+    this.moduleService = moduleService;
+  }
 }
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/partitioned/PersistentPartitionedRegionDistributedTest.java b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/partitioned/PersistentPartitionedRegionDistributedTest.java
index 81777a1..1188889 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/partitioned/PersistentPartitionedRegionDistributedTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/partitioned/PersistentPartitionedRegionDistributedTest.java
@@ -97,6 +97,8 @@ import org.apache.geode.internal.cache.control.InternalResourceManager;
 import org.apache.geode.internal.cache.control.InternalResourceManager.ResourceObserver;
 import org.apache.geode.internal.cache.control.InternalResourceManager.ResourceObserverAdapter;
 import org.apache.geode.internal.cache.persistence.PersistentMemberID;
+import org.apache.geode.logging.internal.log4j.api.LogService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 import org.apache.geode.test.awaitility.GeodeAwaitility;
 import org.apache.geode.test.dunit.AsyncInvocation;
 import org.apache.geode.test.dunit.IgnoredException;
@@ -246,7 +248,8 @@ public class PersistentPartitionedRegionDistributedTest implements Serializable
 
     vm2.invoke(() -> {
       DistributedSystemConfig config = defineDistributedSystem(getSystem(), "");
-      AdminDistributedSystem adminDS = getDistributedSystem(config);
+      AdminDistributedSystem adminDS =
+          getDistributedSystem(config, new ServiceLoaderModuleService(LogService.getLogger()));
       adminDS.connect();
       try {
         adminDS.waitToBeConnected(MINUTES.toMillis(2));
@@ -375,7 +378,8 @@ public class PersistentPartitionedRegionDistributedTest implements Serializable
       vm2.invoke("revoke disk store should fail", () -> {
         assertThatThrownBy(() -> {
           DistributedSystemConfig config = defineDistributedSystem(getSystem(), "");
-          AdminDistributedSystem adminDS = getDistributedSystem(config);
+          AdminDistributedSystem adminDS =
+              getDistributedSystem(config, new ServiceLoaderModuleService(LogService.getLogger()));
           adminDS.connect();
 
           try {
@@ -398,7 +402,8 @@ public class PersistentPartitionedRegionDistributedTest implements Serializable
 
     vm2.invoke(() -> {
       DistributedSystemConfig config = defineDistributedSystem(getSystem(), "");
-      AdminDistributedSystem adminDS = getDistributedSystem(config);
+      AdminDistributedSystem adminDS =
+          getDistributedSystem(config, new ServiceLoaderModuleService(LogService.getLogger()));
       adminDS.connect();
       try {
         adminDS.waitToBeConnected(MINUTES.toMillis(2));
@@ -1651,7 +1656,8 @@ public class PersistentPartitionedRegionDistributedTest implements Serializable
   private void revokeKnownMissingMembers(final int numExpectedMissing)
       throws AdminException, InterruptedException {
     DistributedSystemConfig config = defineDistributedSystem(getSystem(), "");
-    AdminDistributedSystem adminDS = getDistributedSystem(config);
+    AdminDistributedSystem adminDS = getDistributedSystem(config, new ServiceLoaderModuleService(
+        LogService.getLogger()));
     adminDS.connect();
     try {
       adminDS.waitToBeConnected(MINUTES.toMillis(2));
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/partitioned/ShutdownAllDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/partitioned/ShutdownAllDUnitTest.java
index 24272da..e32d389 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/partitioned/ShutdownAllDUnitTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/partitioned/ShutdownAllDUnitTest.java
@@ -57,6 +57,8 @@ import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.cache.PartitionedRegion;
 import org.apache.geode.internal.cache.control.InternalResourceManager;
 import org.apache.geode.internal.cache.control.InternalResourceManager.ResourceObserver;
+import org.apache.geode.logging.internal.log4j.api.LogService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 import org.apache.geode.test.dunit.Assert;
 import org.apache.geode.test.dunit.AsyncInvocation;
 import org.apache.geode.test.dunit.Host;
@@ -620,7 +622,7 @@ public class ShutdownAllDUnitTest extends JUnit4CacheTestCase {
         try {
           config = AdminDistributedSystemFactory.defineDistributedSystem(getSystem(), "");
           adminDS = (AdminDistributedSystemImpl) AdminDistributedSystemFactory
-              .getDistributedSystem(config);
+              .getDistributedSystem(config, new ServiceLoaderModuleService(LogService.getLogger()));
           adminDS.connect();
           Set members = adminDS.shutDownAllMembers();
           int num = members == null ? 0 : members.size();
@@ -846,7 +848,7 @@ public class ShutdownAllDUnitTest extends JUnit4CacheTestCase {
         try {
           config = AdminDistributedSystemFactory.defineDistributedSystem(getSystem(), "");
           adminDS = (AdminDistributedSystemImpl) AdminDistributedSystemFactory
-              .getDistributedSystem(config);
+              .getDistributedSystem(config, new ServiceLoaderModuleService(LogService.getLogger()));
           adminDS.connect();
           Set members = adminDS.shutDownAllMembers(timeout);
           int num = members == null ? 0 : members.size();
diff --git a/geode-core/src/distributedTest/resources/META-INF/services/org.springframework.shell.core.CommandMarker b/geode-core/src/distributedTest/resources/META-INF/services/org.apache.geode.management.cli.GeodeCommandMarker
similarity index 100%
rename from geode-core/src/distributedTest/resources/META-INF/services/org.springframework.shell.core.CommandMarker
rename to geode-core/src/distributedTest/resources/META-INF/services/org.apache.geode.management.cli.GeodeCommandMarker
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/cache/client/internal/AutoConnectionSourceImplJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/cache/client/internal/AutoConnectionSourceImplJUnitTest.java
index 5e783cb..d6ef9cb 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/cache/client/internal/AutoConnectionSourceImplJUnitTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/cache/client/internal/AutoConnectionSourceImplJUnitTest.java
@@ -81,8 +81,10 @@ import org.apache.geode.internal.cache.client.protocol.ClientProtocolServiceLoad
 import org.apache.geode.internal.cache.tier.InternalClientMembership;
 import org.apache.geode.internal.net.SocketCreatorFactory;
 import org.apache.geode.internal.security.SecurableCommunicationChannel;
+import org.apache.geode.logging.internal.log4j.api.LogService;
 import org.apache.geode.management.membership.ClientMembershipEvent;
 import org.apache.geode.management.membership.ClientMembershipListener;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 import org.apache.geode.test.junit.categories.ClientServerTest;
 import org.apache.geode.util.internal.GeodeGlossary;
 
@@ -90,6 +92,8 @@ import org.apache.geode.util.internal.GeodeGlossary;
 @Category(ClientServerTest.class)
 public class AutoConnectionSourceImplJUnitTest {
 
+  @Rule
+  public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
   private Cache cache;
   private int port;
   private FakeHandler handler;
@@ -99,9 +103,6 @@ public class AutoConnectionSourceImplJUnitTest {
   private ScheduledExecutorService background;
   private PoolStats poolStats;
 
-  @Rule
-  public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
-
   @Before
   public void setUp() throws Exception {
     Properties props = new Properties();
@@ -299,7 +300,8 @@ public class AutoConnectionSourceImplJUnitTest {
 
     TcpServer server2 =
         new TcpServer(secondPort, InetAddress.getLocalHost(), handler,
-            "tcp server", new ProtocolCheckerImpl(null, new ClientProtocolServiceLoader()),
+            "tcp server", new ProtocolCheckerImpl(null, new ClientProtocolServiceLoader(
+                new ServiceLoaderModuleService(LogService.getLogger()))),
             DistributionStats::getStatTime,
             Executors::newCachedThreadPool,
             SocketCreatorFactory
@@ -386,7 +388,10 @@ public class AutoConnectionSourceImplJUnitTest {
   private void startFakeLocator() throws IOException, InterruptedException {
 
     server = new TcpServer(port, InetAddress.getLocalHost(), handler,
-        "Tcp Server", new ProtocolCheckerImpl(null, new ClientProtocolServiceLoader()),
+        "Tcp Server",
+        new ProtocolCheckerImpl(null,
+            new ClientProtocolServiceLoader(
+                new ServiceLoaderModuleService(LogService.getLogger()))),
         DistributionStats::getStatTime,
         Executors::newCachedThreadPool,
         SocketCreatorFactory
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/cache/execute/CoreFunctionSecurityTest.java b/geode-core/src/integrationTest/java/org/apache/geode/cache/execute/CoreFunctionSecurityTest.java
index 3b02ee4..2bef07f 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/cache/execute/CoreFunctionSecurityTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/cache/execute/CoreFunctionSecurityTest.java
@@ -27,6 +27,7 @@ import org.junit.Test;
 
 import org.apache.geode.cache.RegionShortcut;
 import org.apache.geode.examples.SimpleSecurityManager;
+import org.apache.geode.logging.internal.log4j.api.LogService;
 import org.apache.geode.management.internal.cli.functions.AlterRuntimeConfigFunction;
 import org.apache.geode.management.internal.cli.functions.ChangeLogLevelFunction;
 import org.apache.geode.management.internal.cli.functions.CloseDurableClientFunction;
@@ -80,6 +81,7 @@ import org.apache.geode.management.internal.configuration.functions.RecreateCach
 import org.apache.geode.management.internal.functions.GetMemberInformationFunction;
 import org.apache.geode.management.internal.functions.RebalanceFunction;
 import org.apache.geode.management.internal.functions.RestoreRedundancyFunction;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 import org.apache.geode.test.junit.rules.ConnectionConfiguration;
 import org.apache.geode.test.junit.rules.GfshCommandRule;
 import org.apache.geode.test.junit.rules.ServerStarterRule;
@@ -101,6 +103,8 @@ public class CoreFunctionSecurityTest {
 
   @BeforeClass
   public static void setupClass() {
+    ServiceLoaderModuleService moduleService = new ServiceLoaderModuleService(
+        LogService.getLogger());
     functionStringMap.put(new AlterRuntimeConfigFunction(), "*");
     functionStringMap.put(new ChangeLogLevelFunction(), "*");
     functionStringMap.put(new CloseDurableClientFunction(), "*");
@@ -113,18 +117,18 @@ public class CoreFunctionSecurityTest {
     functionStringMap.put(new DataCommandFunction(), "*");
     functionStringMap.put(new DeployFunction(), "*");
     functionStringMap.put(new DescribeDiskStoreFunction(), "*");
-    functionStringMap.put(new DestroyAsyncEventQueueFunction(), "*");
-    functionStringMap.put(new DestroyDiskStoreFunction(), "*");
+    functionStringMap.put(new DestroyAsyncEventQueueFunction(moduleService), "*");
+    functionStringMap.put(new DestroyDiskStoreFunction(moduleService), "*");
     functionStringMap.put(new DestroyIndexFunction(), "*");
     functionStringMap.put(new ExportConfigFunction(), "*");
     functionStringMap.put(new ExportDataFunction(), "*");
     functionStringMap.put(new ExportLogsFunction(), "*");
-    functionStringMap.put(new FetchRegionAttributesFunction(), "*");
+    functionStringMap.put(new FetchRegionAttributesFunction(moduleService), "*");
     functionStringMap.put(new FetchSharedConfigurationStatusFunction(), "*");
     functionStringMap.put(new GarbageCollectionFunction(), "*");
     functionStringMap.put(new GatewayReceiverCreateFunction(), "*");
     functionStringMap.put(new GatewaySenderCreateFunction(), "*");
-    functionStringMap.put(new GatewaySenderDestroyFunction(), "*");
+    functionStringMap.put(new GatewaySenderDestroyFunction(moduleService), "*");
     functionStringMap.put(new GetClusterConfigurationFunction(), "*");
     functionStringMap.put(new GetMemberConfigInformationFunction(), "*");
     functionStringMap.put(new GetMemberInformationFunction(), "*");
@@ -143,8 +147,8 @@ public class CoreFunctionSecurityTest {
     functionStringMap.put(new RebalanceFunction(), "*");
     functionStringMap.put(new RestoreRedundancyFunction(), "*");
     functionStringMap.put(new RegionAlterFunction(), "*");
-    functionStringMap.put(new RegionCreateFunction(), "*");
-    functionStringMap.put(new RegionDestroyFunction(), "*");
+    functionStringMap.put(new RegionCreateFunction(moduleService), "*");
+    functionStringMap.put(new RegionDestroyFunction(moduleService), "*");
     functionStringMap.put(new ShowMissingDiskStoresFunction(), "*");
     functionStringMap.put(new ShutDownFunction(), "*");
     functionStringMap.put(new SizeExportLogsFunction(), "*");
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/distributed/ServerLauncherIntegrationTestCase.java b/geode-core/src/integrationTest/java/org/apache/geode/distributed/ServerLauncherIntegrationTestCase.java
index e77d3ea..63b72e6 100755
--- a/geode-core/src/integrationTest/java/org/apache/geode/distributed/ServerLauncherIntegrationTestCase.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/distributed/ServerLauncherIntegrationTestCase.java
@@ -44,6 +44,8 @@ import org.apache.geode.internal.cache.xmlcache.CacheCreation;
 import org.apache.geode.internal.cache.xmlcache.CacheXmlGenerator;
 import org.apache.geode.internal.cache.xmlcache.RegionAttributesCreation;
 import org.apache.geode.internal.process.ProcessType;
+import org.apache.geode.logging.internal.log4j.api.LogService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 
 /**
  * Abstract base class for integration tests of {@link ServerLauncher}.
@@ -184,7 +186,8 @@ public abstract class ServerLauncherIntegrationTestCase extends LauncherIntegrat
   }
 
   private File writeCacheXml(final int serverPort) throws IOException {
-    CacheCreation creation = new CacheCreation();
+    CacheCreation creation = new CacheCreation(new ServiceLoaderModuleService(
+        LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(creation);
     attrs.setDataPolicy(DataPolicy.REPLICATE);
     attrs.setScope(Scope.DISTRIBUTED_ACK);
@@ -203,7 +206,8 @@ public abstract class ServerLauncherIntegrationTestCase extends LauncherIntegrat
       final String hostnameForClients, final int maxConnections, final int maxThreads,
       final int maximumMessageCount, final int messageTimeToLive, final int socketBufferSize)
       throws IOException {
-    CacheCreation creation = new CacheCreation();
+    CacheCreation creation = new CacheCreation(new ServiceLoaderModuleService(
+        LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(creation);
     attrs.setDataPolicy(DataPolicy.REPLICATE);
     attrs.setScope(Scope.DISTRIBUTED_ACK);
@@ -227,7 +231,8 @@ public abstract class ServerLauncherIntegrationTestCase extends LauncherIntegrat
   }
 
   private File writeCacheXml() throws IOException {
-    CacheCreation creation = new CacheCreation();
+    CacheCreation creation = new CacheCreation(new ServiceLoaderModuleService(
+        LogService.getLogger()));
     RegionAttributesCreation attrs = new RegionAttributesCreation(creation);
     attrs.setDataPolicy(DataPolicy.REPLICATE);
     attrs.setScope(Scope.DISTRIBUTED_ACK);
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/InternalDistributedSystemBuilderForTestingIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/InternalDistributedSystemBuilderForTestingIntegrationTest.java
index 7a1ae86..e4de71a 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/InternalDistributedSystemBuilderForTestingIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/InternalDistributedSystemBuilderForTestingIntegrationTest.java
@@ -28,6 +28,8 @@ import org.junit.Test;
 import org.apache.geode.CancelCriterion;
 import org.apache.geode.internal.statistics.StatisticsManager;
 import org.apache.geode.internal.statistics.StatisticsManagerFactory;
+import org.apache.geode.logging.internal.log4j.api.LogService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 
 public class InternalDistributedSystemBuilderForTestingIntegrationTest {
 
@@ -44,10 +46,11 @@ public class InternalDistributedSystemBuilderForTestingIntegrationTest {
         .thenReturn(statisticsManager);
 
     InternalDistributedSystem system =
-        new InternalDistributedSystem.BuilderForTesting(configProperties)
-            .setDistributionManager(distributionManager)
-            .setStatisticsManagerFactory(statisticsManagerFactory)
-            .build();
+        new InternalDistributedSystem.BuilderForTesting(configProperties,
+            new ServiceLoaderModuleService(LogService.getLogger()))
+                .setDistributionManager(distributionManager)
+                .setStatisticsManagerFactory(statisticsManagerFactory)
+                .build();
 
     assertThat(system.isConnected()).isTrue();
     assertThat(system.getDistributionManager()).isSameAs(distributionManager);
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/InternalDistributedSystemBuilderIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/InternalDistributedSystemBuilderIntegrationTest.java
index 5bb5ebe..e913f22 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/InternalDistributedSystemBuilderIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/InternalDistributedSystemBuilderIntegrationTest.java
@@ -26,9 +26,11 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
+import org.apache.geode.logging.internal.log4j.api.LogService;
 import org.apache.geode.metrics.internal.MetricsService;
 import org.apache.geode.security.PostProcessor;
 import org.apache.geode.security.SecurityManager;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 
 public class InternalDistributedSystemBuilderIntegrationTest {
 
@@ -38,7 +40,7 @@ public class InternalDistributedSystemBuilderIntegrationTest {
   @Before
   public void setup() {
     metricsSessionBuilder = mock(MetricsService.Builder.class);
-    when(metricsSessionBuilder.build(any())).thenReturn(mock(MetricsService.class));
+    when(metricsSessionBuilder.build(any(), any())).thenReturn(mock(MetricsService.class));
   }
 
   @After
@@ -52,8 +54,10 @@ public class InternalDistributedSystemBuilderIntegrationTest {
     Properties configProperties = new Properties();
     configProperties.setProperty(NAME, theName);
 
-    system = new InternalDistributedSystem.Builder(configProperties, metricsSessionBuilder)
-        .build();
+    system =
+        new InternalDistributedSystem.Builder(configProperties, metricsSessionBuilder,
+            new ServiceLoaderModuleService(LogService.getLogger()))
+                .build();
 
     assertThat(system.isConnected()).isTrue();
     assertThat(system.getName()).isEqualTo(theName);
@@ -67,9 +71,10 @@ public class InternalDistributedSystemBuilderIntegrationTest {
     SecurityConfig securityConfig = new SecurityConfig(theSecurityManager, thePostProcessor);
     Properties configProperties = new Properties();
 
-    system = new InternalDistributedSystem.Builder(configProperties, metricsSessionBuilder)
-        .setSecurityConfig(securityConfig)
-        .build();
+    system = new InternalDistributedSystem.Builder(configProperties, metricsSessionBuilder,
+        new ServiceLoaderModuleService(LogService.getLogger()))
+            .setSecurityConfig(securityConfig)
+            .build();
 
     assertThat(system.getSecurityService().getSecurityManager())
         .isSameAs(theSecurityManager);
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/InternalDistributedSystemJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/InternalDistributedSystemJUnitTest.java
index eb36865..a9270e7 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/InternalDistributedSystemJUnitTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/InternalDistributedSystemJUnitTest.java
@@ -74,7 +74,9 @@ import org.apache.geode.internal.AvailablePort;
 import org.apache.geode.internal.Config;
 import org.apache.geode.internal.ConfigSource;
 import org.apache.geode.internal.logging.InternalLogWriter;
+import org.apache.geode.logging.internal.log4j.api.LogService;
 import org.apache.geode.metrics.internal.MetricsService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 import org.apache.geode.test.junit.categories.MembershipTest;
 import org.apache.geode.util.internal.GeodeGlossary;
 
@@ -93,8 +95,9 @@ public class InternalDistributedSystemJUnitTest {
 
   private InternalDistributedSystem createSystem(Properties props,
       MetricsService.Builder metricsSessionBuilder) {
-    this.system = new InternalDistributedSystem.Builder(props, metricsSessionBuilder)
-        .build();
+    this.system = new InternalDistributedSystem.Builder(props, metricsSessionBuilder,
+        new ServiceLoaderModuleService(LogService.getLogger()))
+            .build();
     return this.system;
   }
 
@@ -103,7 +106,7 @@ public class InternalDistributedSystemJUnitTest {
    */
   private InternalDistributedSystem createSystem(Properties props) {
     MetricsService.Builder metricsSessionBuilder = mock(MetricsService.Builder.class);
-    when(metricsSessionBuilder.build(any())).thenReturn(mock(MetricsService.class));
+    when(metricsSessionBuilder.build(any(), any())).thenReturn(mock(MetricsService.class));
     return createSystem(props, metricsSessionBuilder);
   }
 
@@ -657,10 +660,11 @@ public class InternalDistributedSystemJUnitTest {
     props.setProperty(LOCATORS, "");
     Config config1 = new DistributionConfigImpl(props, false);
     MetricsService.Builder metricsSessionBuilder = mock(MetricsService.Builder.class);
-    when(metricsSessionBuilder.build(any())).thenReturn(mock(MetricsService.class));
+    when(metricsSessionBuilder.build(any(), any())).thenReturn(mock(MetricsService.class));
     InternalDistributedSystem sys =
-        new InternalDistributedSystem.Builder(config1.toProperties(), metricsSessionBuilder)
-            .build();
+        new InternalDistributedSystem.Builder(config1.toProperties(), metricsSessionBuilder,
+            new ServiceLoaderModuleService(LogService.getLogger()))
+                .build();
     try {
 
       props.put(MCAST_PORT, "1");
@@ -794,18 +798,19 @@ public class InternalDistributedSystemJUnitTest {
   public void usesSessionBuilderToCreateMetricsSession() {
     MetricsService metricsSession = mock(MetricsService.class);
     MetricsService.Builder metricsSessionBuilder = mock(MetricsService.Builder.class);
-    when(metricsSessionBuilder.build(any())).thenReturn(metricsSession);
+    when(metricsSessionBuilder.build(any(), any())).thenReturn(metricsSession);
 
     createSystem(getCommonProperties(), metricsSessionBuilder);
 
-    verify(metricsSessionBuilder).build(system);
+    verify(metricsSessionBuilder).build(system, new ServiceLoaderModuleService(
+        LogService.getLogger()));
   }
 
   @Test
   public void startsMetricsSession() {
     MetricsService metricsSession = mock(MetricsService.class);
     MetricsService.Builder metricsSessionBuilder = mock(MetricsService.Builder.class);
-    when(metricsSessionBuilder.build(any())).thenReturn(metricsSession);
+    when(metricsSessionBuilder.build(any(), any())).thenReturn(metricsSession);
     when(metricsSession.getMeterRegistry()).thenReturn(mock(MeterRegistry.class));
 
     createSystem(getCommonProperties(), metricsSessionBuilder);
@@ -821,7 +826,7 @@ public class InternalDistributedSystemJUnitTest {
     when(metricsSession.getMeterRegistry()).thenReturn(sessionMeterRegistry);
 
     MetricsService.Builder metricsSessionBuilder = mock(MetricsService.Builder.class);
-    when(metricsSessionBuilder.build(any())).thenReturn(metricsSession);
+    when(metricsSessionBuilder.build(any(), any())).thenReturn(metricsSession);
     when(metricsSession.getMeterRegistry()).thenReturn(sessionMeterRegistry);
 
     createSystem(getCommonProperties(), metricsSessionBuilder);
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/InternalDistributedSystemLockMemoryIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/InternalDistributedSystemLockMemoryIntegrationTest.java
index 075ad0b..1e47242 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/InternalDistributedSystemLockMemoryIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/InternalDistributedSystemLockMemoryIntegrationTest.java
@@ -32,7 +32,9 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.contrib.java.lang.system.RestoreSystemProperties;
 
+import org.apache.geode.logging.internal.log4j.api.LogService;
 import org.apache.geode.metrics.internal.MetricsService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 import org.apache.geode.util.internal.GeodeGlossary;
 
 public class InternalDistributedSystemLockMemoryIntegrationTest {
@@ -46,7 +48,7 @@ public class InternalDistributedSystemLockMemoryIntegrationTest {
   @Before
   public void setUp() {
     builder = mock(MetricsService.Builder.class);
-    when(builder.build(any())).thenReturn(mock(MetricsService.class));
+    when(builder.build(any(), any())).thenReturn(mock(MetricsService.class));
   }
 
   @After
@@ -59,7 +61,8 @@ public class InternalDistributedSystemLockMemoryIntegrationTest {
   @Test
   public void lockMemoryAllowedIfAllowMemoryOverCommitIsSet() {
     System.setProperty(GeodeGlossary.GEMFIRE_PREFIX + "Cache.ALLOW_MEMORY_OVERCOMMIT", "true");
-    system = spy(new InternalDistributedSystem.Builder(new Properties(), builder).build());
+    system = spy(new InternalDistributedSystem.Builder(new Properties(), builder,
+        new ServiceLoaderModuleService(LogService.getLogger())).build());
     doNothing().when(system).lockMemory();
 
     system.lockMemory(100, 200);
@@ -71,7 +74,8 @@ public class InternalDistributedSystemLockMemoryIntegrationTest {
   public void lockMemoryAvoidedIfAvoidMemoryLockWhenOverCommitIsSet() {
     System.setProperty(
         GeodeGlossary.GEMFIRE_PREFIX + "Cache.AVOID_MEMORY_LOCK_WHEN_OVERCOMMIT", "true");
-    system = spy(new InternalDistributedSystem.Builder(new Properties(), builder).build());
+    system = spy(new InternalDistributedSystem.Builder(new Properties(), builder,
+        new ServiceLoaderModuleService(LogService.getLogger())).build());
 
     system.lockMemory(100, 200);
 
@@ -83,7 +87,8 @@ public class InternalDistributedSystemLockMemoryIntegrationTest {
     System.setProperty(GeodeGlossary.GEMFIRE_PREFIX + "Cache.ALLOW_MEMORY_OVERCOMMIT", "true");
     System.setProperty(
         GeodeGlossary.GEMFIRE_PREFIX + "Cache.AVOID_MEMORY_LOCK_WHEN_OVERCOMMIT", "true");
-    system = spy(new InternalDistributedSystem.Builder(new Properties(), builder).build());
+    system = spy(new InternalDistributedSystem.Builder(new Properties(), builder,
+        new ServiceLoaderModuleService(LogService.getLogger())).build());
 
     system.lockMemory(100, 200);
 
@@ -93,7 +98,8 @@ public class InternalDistributedSystemLockMemoryIntegrationTest {
 
   @Test
   public void lockMemoryThrowsIfMemoryOverCommit() {
-    system = spy(new InternalDistributedSystem.Builder(new Properties(), builder).build());
+    system = spy(new InternalDistributedSystem.Builder(new Properties(), builder,
+        new ServiceLoaderModuleService(LogService.getLogger())).build());
 
     Throwable caughtException = catchThrowable(() -> system.lockMemory(100, 200));
 
@@ -103,7 +109,8 @@ public class InternalDistributedSystemLockMemoryIntegrationTest {
 
   @Test
   public void locksMemoryIfMemoryNotOverCommit() {
-    system = spy(new InternalDistributedSystem.Builder(new Properties(), builder).build());
+    system = spy(new InternalDistributedSystem.Builder(new Properties(), builder,
+        new ServiceLoaderModuleService(LogService.getLogger())).build());
     doNothing().when(system).lockMemory();
 
     system.lockMemory(200, 100);
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/InternalDistributedSystemSecurityIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/InternalDistributedSystemSecurityIntegrationTest.java
index 61286a9..a0cd6be 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/InternalDistributedSystemSecurityIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/InternalDistributedSystemSecurityIntegrationTest.java
@@ -26,9 +26,11 @@ import org.junit.Before;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
+import org.apache.geode.logging.internal.log4j.api.LogService;
 import org.apache.geode.metrics.internal.MetricsService;
 import org.apache.geode.security.PostProcessor;
 import org.apache.geode.security.SecurityManager;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 import org.apache.geode.test.junit.categories.SecurityTest;
 
 @Category(SecurityTest.class)
@@ -40,7 +42,7 @@ public class InternalDistributedSystemSecurityIntegrationTest {
   @Before
   public void setup() {
     metricsSessionBuilder = mock(MetricsService.Builder.class);
-    when(metricsSessionBuilder.build(any())).thenReturn(mock(MetricsService.class));
+    when(metricsSessionBuilder.build(any(), any())).thenReturn(mock(MetricsService.class));
   }
 
   @After
@@ -58,7 +60,7 @@ public class InternalDistributedSystemSecurityIntegrationTest {
 
     system =
         InternalDistributedSystem.connectInternal(configProperties, securityConfig,
-            metricsSessionBuilder);
+            metricsSessionBuilder, new ServiceLoaderModuleService(LogService.getLogger()));
 
     system.disconnect();
 
@@ -74,7 +76,8 @@ public class InternalDistributedSystemSecurityIntegrationTest {
     Properties configProperties = new Properties();
 
     system = InternalDistributedSystem.connectInternal(
-        configProperties, securityConfig, metricsSessionBuilder);
+        configProperties, securityConfig, metricsSessionBuilder,
+        new ServiceLoaderModuleService(LogService.getLogger()));
 
     system.disconnect();
 
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/InternalLocatorIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/InternalLocatorIntegrationTest.java
index 09efe36..6398817 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/InternalLocatorIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/InternalLocatorIntegrationTest.java
@@ -40,6 +40,8 @@ import org.apache.geode.distributed.Locator;
 import org.apache.geode.internal.logging.InternalLogWriter;
 import org.apache.geode.internal.security.SecurableCommunicationChannel;
 import org.apache.geode.logging.internal.LoggingSession;
+import org.apache.geode.logging.internal.log4j.api.LogService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 
 public class InternalLocatorIntegrationTest {
 
@@ -99,7 +101,7 @@ public class InternalLocatorIntegrationTest {
       internalLocator =
           new InternalLocator(port, loggingSession, logFile, logWriter, securityLogWriter,
               bindAddress, hostnameForClients, distributedSystemProperties, distributionConfig,
-              workingDirectory);
+              workingDirectory, new ServiceLoaderModuleService(LogService.getLogger()));
     }).doesNotThrowAnyException();
   }
 
@@ -107,7 +109,8 @@ public class InternalLocatorIntegrationTest {
   public void restartingClusterConfigurationDoesNotThrowException() throws IOException {
     internalLocator = InternalLocator.startLocator(port, logFile, logWriter,
         securityLogWriter, bindAddress, true,
-        distributedSystemProperties, hostnameForClients, workingDirectory);
+        distributedSystemProperties, hostnameForClients, workingDirectory,
+        new ServiceLoaderModuleService(LogService.getLogger()));
     port = internalLocator.getPort();
     internalLocator.stop(true, true, false);
     assertThat(InternalLocator.getLocator()).isNull();
@@ -121,7 +124,8 @@ public class InternalLocatorIntegrationTest {
   public void startedLocatorIsRunning() throws IOException {
     internalLocator = InternalLocator.startLocator(port, logFile, logWriter,
         securityLogWriter, bindAddress, true,
-        distributedSystemProperties, hostnameForClients, workingDirectory);
+        distributedSystemProperties, hostnameForClients, workingDirectory,
+        new ServiceLoaderModuleService(LogService.getLogger()));
     port = internalLocator.getPort();
 
     assertThat(internalLocator.isStopped()).isFalse();
@@ -131,7 +135,8 @@ public class InternalLocatorIntegrationTest {
   public void startedLocatorHasLocator() throws IOException {
     internalLocator = InternalLocator.startLocator(port, logFile, logWriter,
         securityLogWriter, bindAddress, true,
-        distributedSystemProperties, hostnameForClients, workingDirectory);
+        distributedSystemProperties, hostnameForClients, workingDirectory,
+        new ServiceLoaderModuleService(LogService.getLogger()));
     port = internalLocator.getPort();
 
     assertThat(InternalLocator.hasLocator()).isTrue();
@@ -141,7 +146,8 @@ public class InternalLocatorIntegrationTest {
   public void stoppedLocatorIsStopped() throws IOException {
     internalLocator = InternalLocator.startLocator(port, logFile, logWriter,
         securityLogWriter, bindAddress, true,
-        distributedSystemProperties, hostnameForClients, workingDirectory);
+        distributedSystemProperties, hostnameForClients, workingDirectory,
+        new ServiceLoaderModuleService(LogService.getLogger()));
     port = internalLocator.getPort();
 
     internalLocator.stop();
@@ -153,7 +159,8 @@ public class InternalLocatorIntegrationTest {
   public void stoppedLocatorDoesNotHaveLocator() throws IOException {
     internalLocator = InternalLocator.startLocator(port, logFile, logWriter,
         securityLogWriter, bindAddress, true,
-        distributedSystemProperties, hostnameForClients, workingDirectory);
+        distributedSystemProperties, hostnameForClients, workingDirectory,
+        new ServiceLoaderModuleService(LogService.getLogger()));
     port = internalLocator.getPort();
 
     internalLocator.stop();
@@ -172,7 +179,9 @@ public class InternalLocatorIntegrationTest {
     properties.put("load-cluster-configuration-from-dir", "true");
     assertThatThrownBy(() -> InternalLocator.startLocator(port, logFile, logWriter,
         securityLogWriter, bindAddress, true,
-        properties, hostnameForClients, workingDirectory)).isInstanceOf(RuntimeException.class);
+        properties, hostnameForClients, workingDirectory, new ServiceLoaderModuleService(
+            LogService.getLogger())))
+                .isInstanceOf(RuntimeException.class);
 
     assertThat(InternalLocator.hasLocator()).isFalse();
   }
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/MembershipJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/MembershipJUnitTest.java
index cb3c19a..1d92e3d 100755
--- a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/MembershipJUnitTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/MembershipJUnitTest.java
@@ -78,6 +78,8 @@ import org.apache.geode.internal.security.SecurableCommunicationChannel;
 import org.apache.geode.internal.security.SecurityService;
 import org.apache.geode.internal.security.SecurityServiceFactory;
 import org.apache.geode.internal.serialization.DSFIDSerializer;
+import org.apache.geode.logging.internal.log4j.api.LogService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 
 @Category({MembershipJUnitTest.class})
 public class MembershipJUnitTest {
@@ -143,7 +145,8 @@ public class MembershipJUnitTest {
       // to be created
       internalLocator =
           InternalLocator.startLocator(port, new File(""), null, null, localHost, false,
-              new Properties(), null, temporaryFolder.getRoot().toPath());
+              new Properties(), null, temporaryFolder.getRoot().toPath(),
+              new ServiceLoaderModuleService(LogService.getLogger()));
 
       // create configuration objects
       Properties nonDefault = new Properties();
@@ -294,7 +297,8 @@ public class MembershipJUnitTest {
             mockSystem.getSecurityLogWriter(), mockSystem.getInternalLogWriter());
     final Membership<InternalDistributedMember> m1 =
         MembershipBuilder.<InternalDistributedMember>newMembershipBuilder(
-            socketCreator, locatorClient, serializer, memberIdentifierFactory)
+            socketCreator, locatorClient, serializer, memberIdentifierFactory,
+            new ServiceLoaderModuleService(LogService.getLogger()))
             .setMembershipLocator(locator)
             .setAuthenticator(authenticator)
             .setStatistics(stats1)
@@ -335,7 +339,8 @@ public class MembershipJUnitTest {
       // to be created
       internalLocator =
           InternalLocator.startLocator(port, new File(""), null, null, localHost, false, p, null,
-              temporaryFolder.getRoot().toPath());
+              temporaryFolder.getRoot().toPath(), new ServiceLoaderModuleService(
+                  LogService.getLogger()));
 
       // create configuration objects
       Properties nonDefault = new Properties();
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/ServerBuilderIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/ServerBuilderIntegrationTest.java
index b898175..666f9f4 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/ServerBuilderIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/ServerBuilderIntegrationTest.java
@@ -36,6 +36,8 @@ import org.apache.geode.cache.wan.GatewayReceiver;
 import org.apache.geode.cache.wan.GatewayTransportFilter;
 import org.apache.geode.internal.cache.tier.Acceptor;
 import org.apache.geode.internal.statistics.StatisticsClockFactory;
+import org.apache.geode.logging.internal.log4j.api.LogService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 import org.apache.geode.test.junit.categories.ClientServerTest;
 
 @Category(ClientServerTest.class)
@@ -66,8 +68,9 @@ public class ServerBuilderIntegrationTest {
   @Test
   public void byDefaultCreatesServerWithCacheServerAcceptor() throws IOException {
     server = new ServerBuilder(cache, cache.getSecurityService(),
-        StatisticsClockFactory.disabledClock())
-            .createServer();
+        StatisticsClockFactory.disabledClock(), new ServiceLoaderModuleService(
+            LogService.getLogger()))
+                .createServer();
     server.setPort(0);
 
     server.start();
@@ -81,9 +84,10 @@ public class ServerBuilderIntegrationTest {
     when(gatewayReceiver.getGatewayTransportFilters())
         .thenReturn(singletonList(mock(GatewayTransportFilter.class)));
     server = new ServerBuilder(cache, cache.getSecurityService(),
-        StatisticsClockFactory.disabledClock())
-            .forGatewayReceiver(gatewayReceiver)
-            .createServer();
+        StatisticsClockFactory.disabledClock(), new ServiceLoaderModuleService(
+            LogService.getLogger()))
+                .forGatewayReceiver(gatewayReceiver)
+                .createServer();
     server.setPort(0);
 
     server.start();
@@ -98,8 +102,9 @@ public class ServerBuilderIntegrationTest {
     String membershipGroup = "group-m0";
     cache = (InternalCache) new CacheFactory().set(GROUPS, membershipGroup).create();
     server = new ServerBuilder(cache, cache.getSecurityService(),
-        StatisticsClockFactory.disabledClock())
-            .createServer();
+        StatisticsClockFactory.disabledClock(), new ServiceLoaderModuleService(
+            LogService.getLogger()))
+                .createServer();
 
     assertThat(server.getCombinedGroups()).containsExactly(membershipGroup);
   }
@@ -112,9 +117,10 @@ public class ServerBuilderIntegrationTest {
     String membershipGroup = "group-m0";
     cache = (InternalCache) new CacheFactory().set(GROUPS, membershipGroup).create();
     server = new ServerBuilder(cache, cache.getSecurityService(),
-        StatisticsClockFactory.disabledClock())
-            .forGatewayReceiver(gatewayReceiver)
-            .createServer();
+        StatisticsClockFactory.disabledClock(), new ServiceLoaderModuleService(
+            LogService.getLogger()))
+                .forGatewayReceiver(gatewayReceiver)
+                .createServer();
 
     assertThat(server.getCombinedGroups()).doesNotContain(membershipGroup);
   }
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/tier/sockets/AcceptorImplIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/tier/sockets/AcceptorImplIntegrationTest.java
index ba7aa70..d90f5ed 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/tier/sockets/AcceptorImplIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/tier/sockets/AcceptorImplIntegrationTest.java
@@ -40,6 +40,8 @@ import org.junit.experimental.categories.Category;
 import org.apache.geode.cache.CacheFactory;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.cache.tier.Acceptor;
+import org.apache.geode.logging.internal.log4j.api.LogService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 import org.apache.geode.test.junit.categories.ClientServerTest;
 
 @Category(ClientServerTest.class)
@@ -53,7 +55,8 @@ public class AcceptorImplIntegrationTest {
   @Before
   public void setUp() throws Exception {
     cache = (InternalCache) new CacheFactory().create();
-    serverConnectionFactory = new ServerConnectionFactory();
+    serverConnectionFactory = new ServerConnectionFactory(new ServiceLoaderModuleService(
+        LogService.getLogger()));
   }
 
   @After
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/xmlcache/CacheXmlGeneratorIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/xmlcache/CacheXmlGeneratorIntegrationTest.java
index 350686c..3a94388 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/xmlcache/CacheXmlGeneratorIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/xmlcache/CacheXmlGeneratorIntegrationTest.java
@@ -34,6 +34,8 @@ import org.apache.geode.cache.Cache;
 import org.apache.geode.cache.PartitionAttributes;
 import org.apache.geode.cache.PartitionAttributesFactory;
 import org.apache.geode.cache.Region;
+import org.apache.geode.logging.internal.log4j.api.LogService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 import org.apache.geode.test.junit.rules.ServerStarterRule;
 
 @RunWith(Parameterized.class)
@@ -61,7 +63,8 @@ public class CacheXmlGeneratorIntegrationTest {
   @Test
   public void generateXmlForPartitionRegionWithOffHeapWhenDistributedSystemDoesNotExistShouldWorkProperly()
       throws Exception {
-    CacheCreation cacheCreation = new CacheCreation();
+    CacheCreation cacheCreation = new CacheCreation(new ServiceLoaderModuleService(
+        LogService.getLogger()));
     RegionAttributesCreation attributes = new RegionAttributesCreation(cacheCreation);
     attributes.setOffHeap(true);
     attributes.setPartitionAttributes(partitionAttributes);
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/xmlcache/CacheXmlParserJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/xmlcache/CacheXmlParserJUnitTest.java
index 0876d6e..1321ba8 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/xmlcache/CacheXmlParserJUnitTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/xmlcache/CacheXmlParserJUnitTest.java
@@ -39,6 +39,8 @@ import org.apache.geode.cache.DiskStore;
 import org.apache.geode.cache.client.ClientCache;
 import org.apache.geode.cache.client.ClientCacheFactory;
 import org.apache.geode.distributed.internal.InternalDistributedSystem;
+import org.apache.geode.logging.internal.log4j.api.LogService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 
 /**
  * Test cases for {@link CacheXmlParser}.
@@ -75,6 +77,7 @@ public class CacheXmlParserJUnitTest {
   @Test
   public void testGetDelegate() {
     final TestCacheXmlParser cacheXmlParser = new TestCacheXmlParser();
+    cacheXmlParser.init(new ServiceLoaderModuleService(LogService.getLogger()));
     assertThat(cacheXmlParser.getDelegates()).as("delegates should be empty.").isEmpty();
 
     final MockXmlParser delegate = (MockXmlParser) cacheXmlParser.getDelegate(NAMESPACE_URI);
@@ -177,13 +180,15 @@ public class CacheXmlParserJUnitTest {
   @Test
   public void testDTDFallbackWithNonEnglishLocal() {
     CacheXmlParser.parse(this.getClass().getResourceAsStream(
-        "CacheXmlParserJUnitTest.testDTDFallbackWithNonEnglishLocal.cache.xml"));
+        "CacheXmlParserJUnitTest.testDTDFallbackWithNonEnglishLocal.cache.xml"),
+        new ServiceLoaderModuleService(LogService.getLogger()));
 
     final Locale previousLocale = Locale.getDefault();
     try {
       Locale.setDefault(Locale.JAPAN);
       CacheXmlParser.parse(this.getClass().getResourceAsStream(
-          "CacheXmlParserJUnitTest.testDTDFallbackWithNonEnglishLocal.cache.xml"));
+          "CacheXmlParserJUnitTest.testDTDFallbackWithNonEnglishLocal.cache.xml"),
+          new ServiceLoaderModuleService(LogService.getLogger()));
     } finally {
       Locale.setDefault(previousLocale);
     }
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/EntityInfoIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/EntityInfoIntegrationTest.java
index 2adb253..4ea653b 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/EntityInfoIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/EntityInfoIntegrationTest.java
@@ -20,6 +20,8 @@ import static org.assertj.core.api.Assertions.assertThat;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
+import org.apache.geode.logging.internal.log4j.api.LogService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
 /**
@@ -30,6 +32,7 @@ public class EntityInfoIntegrationTest {
 
   @Test
   public void getConfigurationInfoContainsLog4j2Xml() {
-    assertThat(getConfigurationInfo()).contains("log4j2.xml");
+    assertThat(getConfigurationInfo(new ServiceLoaderModuleService(LogService.getLogger())))
+        .contains("log4j2.xml");
   }
 }
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/StartupConfigurationLoggingIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/StartupConfigurationLoggingIntegrationTest.java
index 6b9c09f..495f635 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/StartupConfigurationLoggingIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/StartupConfigurationLoggingIntegrationTest.java
@@ -43,6 +43,7 @@ import org.apache.geode.distributed.internal.DistributionConfig;
 import org.apache.geode.distributed.internal.InternalDistributedSystem;
 import org.apache.geode.internal.logging.Banner;
 import org.apache.geode.logging.internal.log4j.api.LogService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 import org.apache.geode.test.assertj.LogFileAssert;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
@@ -78,7 +79,7 @@ public class StartupConfigurationLoggingIntegrationTest {
 
     system = (InternalDistributedSystem) DistributedSystem.connect(config);
 
-    banner = new Banner().getString();
+    banner = new Banner(new ServiceLoaderModuleService(LogService.getLogger())).getString();
 
     DistributionConfig distributionConfig = system.getConfig();
     startupConfiguration = StringUtils
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/api/LoggingWithLocatorIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/api/LoggingWithLocatorIntegrationTest.java
index 91d3691..b9cc962 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/api/LoggingWithLocatorIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/api/LoggingWithLocatorIntegrationTest.java
@@ -44,6 +44,7 @@ import org.apache.geode.internal.AvailablePort;
 import org.apache.geode.logging.internal.log4j.LogWriterLogger;
 import org.apache.geode.logging.internal.log4j.api.LogService;
 import org.apache.geode.logging.internal.spi.LogConfig;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 import org.apache.geode.test.assertj.LogFileAssert;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
@@ -92,7 +93,7 @@ public class LoggingWithLocatorIntegrationTest {
     Properties config = new Properties();
 
     locator = InternalLocator.startLocator(port, null, null, null, null, false, config, null,
-        temporaryFolder.getRoot().toPath());
+        temporaryFolder.getRoot().toPath(), new ServiceLoaderModuleService(LogService.getLogger()));
 
     LogConfig logConfig = locator.getLogConfig();
 
@@ -111,7 +112,7 @@ public class LoggingWithLocatorIntegrationTest {
     Properties config = new Properties();
 
     locator = InternalLocator.startLocator(port, logFile, null, null, null, false, config, null,
-        temporaryFolder.getRoot().toPath());
+        temporaryFolder.getRoot().toPath(), new ServiceLoaderModuleService(LogService.getLogger()));
 
     LogConfig logConfig = locator.getLogConfig();
 
@@ -169,7 +170,7 @@ public class LoggingWithLocatorIntegrationTest {
     config.setProperty(ENABLE_CLUSTER_CONFIGURATION, "false");
 
     locator = InternalLocator.startLocator(port, null, null, null, null, false, config, null,
-        temporaryFolder.getRoot().toPath());
+        temporaryFolder.getRoot().toPath(), new ServiceLoaderModuleService(LogService.getLogger()));
     Logger logger = LogService.getLogger();
 
     // assert that logging goes to logFile
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/management/internal/configuration/utils/XmlUtilsAddNewNodeJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/management/internal/configuration/utils/XmlUtilsAddNewNodeJUnitTest.java
index 20e7ae1..19b40e3 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/management/internal/configuration/utils/XmlUtilsAddNewNodeJUnitTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/management/internal/configuration/utils/XmlUtilsAddNewNodeJUnitTest.java
@@ -39,11 +39,14 @@ import org.apache.geode.cache.CacheFactory;
 import org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
 import org.apache.geode.internal.cache.extension.Extension;
 import org.apache.geode.internal.cache.xmlcache.CacheXml;
+import org.apache.geode.logging.internal.log4j.api.LogService;
 import org.apache.geode.management.internal.configuration.domain.XmlEntity;
 import org.apache.geode.management.internal.configuration.utils.XmlUtils.XPathContext;
+import org.apache.geode.services.module.ModuleService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 
 /**
- * Unit tests for {@link XmlUtils#addNewNode(Document, XmlEntity)} and
+ * Unit tests for {@link XmlUtils#addNewNode(Document, XmlEntity, ModuleService)} and
  * {@link XmlUtils#deleteNode(Document, XmlEntity)}. Simulates the
  * {@link InternalConfigurationPersistenceService} method of extracting {@link XmlEntity} from the
  * new
@@ -74,7 +77,8 @@ public class XmlUtilsAddNewNodeJUnitTest {
   @Before
   public void before() throws SAXException, ParserConfigurationException, IOException {
     config = XmlUtils.createDocumentFromReader(new InputStreamReader(
-        this.getClass().getResourceAsStream("XmlUtilsAddNewNodeJUnitTest.xml")));
+        this.getClass().getResourceAsStream("XmlUtilsAddNewNodeJUnitTest.xml")),
+        new ServiceLoaderModuleService(LogService.getLogger()));
   }
 
   @AfterClass
@@ -84,7 +88,8 @@ public class XmlUtilsAddNewNodeJUnitTest {
   }
 
   /**
-   * Tests {@link XmlUtils#addNewNode(Document, XmlEntity)} with {@link CacheXml} element with a
+   * Tests {@link XmlUtils#addNewNode(Document, XmlEntity, ModuleService)} with {@link CacheXml}
+   * element with a
    * <code>name</code> attribute, <code>region</code>. It should be added after other
    * <code>region</code> elements.
    *
@@ -97,15 +102,16 @@ public class XmlUtilsAddNewNodeJUnitTest {
     assertEquals(0, nodes.getLength());
 
     final Document changes = XmlUtils.createDocumentFromReader(new InputStreamReader(this.getClass()
-        .getResourceAsStream("XmlUtilsAddNewNodeJUnitTest.testAddNewNodeNewNamed.xml")));
+        .getResourceAsStream("XmlUtilsAddNewNodeJUnitTest.testAddNewNodeNewNamed.xml")),
+        new ServiceLoaderModuleService(LogService.getLogger()));
     nodes = XmlUtils.query(changes, xPath, xPathContext);
     assertEquals(1, nodes.getLength());
     Element element = (Element) nodes.item(0);
     assertEquals(CacheXml.GEODE_NAMESPACE, element.getNamespaceURI());
 
     final XmlEntity xmlEntity = XmlEntity.builder().withType("region").withAttribute("name", "r3")
-        .withConfig(changes).build();
-    XmlUtils.addNewNode(config, xmlEntity);
+        .withConfig(changes).build(new ServiceLoaderModuleService(LogService.getLogger()));
+    XmlUtils.addNewNode(config, xmlEntity, new ServiceLoaderModuleService(LogService.getLogger()));
 
     nodes = XmlUtils.query(config, xPath, xPathContext);
     assertEquals(1, nodes.getLength());
@@ -135,7 +141,8 @@ public class XmlUtilsAddNewNodeJUnitTest {
   }
 
   /**
-   * Tests {@link XmlUtils#addNewNode(Document, XmlEntity)} with {@link CacheXml} element that does
+   * Tests {@link XmlUtils#addNewNode(Document, XmlEntity, ModuleService)} with {@link CacheXml}
+   * element that does
    * not have a name or id attribute, <code>jndi-bindings</code>. It should be added between
    * <code>pdx</code> and <code>region</code> elements.
    *
@@ -148,15 +155,17 @@ public class XmlUtilsAddNewNodeJUnitTest {
     assertEquals(0, nodes.getLength());
 
     final Document changes = XmlUtils.createDocumentFromReader(new InputStreamReader(this.getClass()
-        .getResourceAsStream("XmlUtilsAddNewNodeJUnitTest.testAddNewNodeNewUnnamed.xml")));
+        .getResourceAsStream("XmlUtilsAddNewNodeJUnitTest.testAddNewNodeNewUnnamed.xml")),
+        new ServiceLoaderModuleService(LogService.getLogger()));
     nodes = XmlUtils.query(changes, xPath, xPathContext);
     assertEquals(1, nodes.getLength());
     Element element = (Element) nodes.item(0);
     assertEquals(CacheXml.GEODE_NAMESPACE, element.getNamespaceURI());
 
     final XmlEntity xmlEntity =
-        XmlEntity.builder().withType("jndi-bindings").withConfig(changes).build();
-    XmlUtils.addNewNode(config, xmlEntity);
+        XmlEntity.builder().withType("jndi-bindings").withConfig(changes)
+            .build(new ServiceLoaderModuleService(LogService.getLogger()));
+    XmlUtils.addNewNode(config, xmlEntity, new ServiceLoaderModuleService(LogService.getLogger()));
 
     nodes = XmlUtils.query(config, xPath, xPathContext);
     assertEquals(1, nodes.getLength());
@@ -170,7 +179,8 @@ public class XmlUtilsAddNewNodeJUnitTest {
   }
 
   /**
-   * Tests {@link XmlUtils#addNewNode(Document, XmlEntity)} with an {@link Extension} that does not
+   * Tests {@link XmlUtils#addNewNode(Document, XmlEntity, ModuleService)} with an {@link Extension}
+   * that does not
    * have a name or id attribute. It should be added to the end of the config xml. Attempts a name
    * collision with test:region, it should not collide with the similarly named cache:region
    * element.
@@ -184,7 +194,8 @@ public class XmlUtilsAddNewNodeJUnitTest {
     assertEquals(0, nodes.getLength());
 
     final Document changes = XmlUtils.createDocumentFromReader(new InputStreamReader(this.getClass()
-        .getResourceAsStream("XmlUtilsAddNewNodeJUnitTest.testAddNewNodeNewUnnamedExtension.xml")));
+        .getResourceAsStream("XmlUtilsAddNewNodeJUnitTest.testAddNewNodeNewUnnamedExtension.xml")),
+        new ServiceLoaderModuleService(LogService.getLogger()));
     nodes = XmlUtils.query(changes, xPath, xPathContext);
     assertEquals(1, nodes.getLength());
     Element element = (Element) nodes.item(0);
@@ -192,8 +203,9 @@ public class XmlUtilsAddNewNodeJUnitTest {
     assertEquals("test:region", element.getNodeName());
 
     final XmlEntity xmlEntity = XmlEntity.builder().withType("region")
-        .withNamespace(TEST_PREFIX, TEST_NAMESPACE).withConfig(changes).build();
-    XmlUtils.addNewNode(config, xmlEntity);
+        .withNamespace(TEST_PREFIX, TEST_NAMESPACE).withConfig(changes)
+        .build(new ServiceLoaderModuleService(LogService.getLogger()));
+    XmlUtils.addNewNode(config, xmlEntity, new ServiceLoaderModuleService(LogService.getLogger()));
 
     nodes = XmlUtils.query(config, xPath, xPathContext);
     assertEquals(1, nodes.getLength());
@@ -210,7 +222,8 @@ public class XmlUtilsAddNewNodeJUnitTest {
   }
 
   /**
-   * Tests {@link XmlUtils#addNewNode(Document, XmlEntity)} with {@link CacheXml} element with a
+   * Tests {@link XmlUtils#addNewNode(Document, XmlEntity, ModuleService)} with {@link CacheXml}
+   * element with a
    * <code>name</code> attribute, <code>region</code>. It should replace existing
    * <code>region</code> element with same <code>name</code>.
    *
@@ -226,7 +239,8 @@ public class XmlUtilsAddNewNodeJUnitTest {
     assertEquals(CacheXml.GEODE_NAMESPACE, element.getNamespaceURI());
 
     final Document changes = XmlUtils.createDocumentFromReader(new InputStreamReader(this.getClass()
-        .getResourceAsStream("XmlUtilsAddNewNodeJUnitTest.testAddNewNodeReplaceNamed.xml")));
+        .getResourceAsStream("XmlUtilsAddNewNodeJUnitTest.testAddNewNodeReplaceNamed.xml")),
+        new ServiceLoaderModuleService(LogService.getLogger()));
     nodes = XmlUtils.query(changes, xPath, xPathContext);
     assertEquals(1, nodes.getLength());
     element = (Element) nodes.item(0);
@@ -234,8 +248,8 @@ public class XmlUtilsAddNewNodeJUnitTest {
     assertEquals(CacheXml.GEODE_NAMESPACE, element.getNamespaceURI());
 
     final XmlEntity xmlEntity = XmlEntity.builder().withType("region").withAttribute("name", "r1")
-        .withConfig(changes).build();
-    XmlUtils.addNewNode(config, xmlEntity);
+        .withConfig(changes).build(new ServiceLoaderModuleService(LogService.getLogger()));
+    XmlUtils.addNewNode(config, xmlEntity, new ServiceLoaderModuleService(LogService.getLogger()));
 
     nodes = XmlUtils.query(config, xPath, xPathContext);
     assertEquals(1, nodes.getLength());
@@ -245,7 +259,8 @@ public class XmlUtilsAddNewNodeJUnitTest {
   }
 
   /**
-   * Tests {@link XmlUtils#addNewNode(Document, XmlEntity)} with {@link CacheXml} element that does
+   * Tests {@link XmlUtils#addNewNode(Document, XmlEntity, ModuleService)} with {@link CacheXml}
+   * element that does
    * not have a name or id attribute, <code>pdx</code>. It should replace <code>pdx</code> element.
    *
    * @since GemFire 8.1
@@ -260,15 +275,18 @@ public class XmlUtilsAddNewNodeJUnitTest {
     assertEquals(CacheXml.GEODE_NAMESPACE, element.getNamespaceURI());
 
     final Document changes = XmlUtils.createDocumentFromReader(new InputStreamReader(this.getClass()
-        .getResourceAsStream("XmlUtilsAddNewNodeJUnitTest.testAddNewNodeReplaceUnnamed.xml")));
+        .getResourceAsStream("XmlUtilsAddNewNodeJUnitTest.testAddNewNodeReplaceUnnamed.xml")),
+        new ServiceLoaderModuleService(LogService.getLogger()));
     nodes = XmlUtils.query(changes, xPath, xPathContext);
     assertEquals(1, nodes.getLength());
     element = (Element) nodes.item(0);
     assertEquals("bar", XmlUtils.getAttribute(element, "disk-store-name"));
     assertEquals(CacheXml.GEODE_NAMESPACE, element.getNamespaceURI());
 
-    final XmlEntity xmlEntity = XmlEntity.builder().withType("pdx").withConfig(changes).build();
-    XmlUtils.addNewNode(config, xmlEntity);
+    final XmlEntity xmlEntity =
+        XmlEntity.builder().withType("pdx").withConfig(changes)
+            .build(new ServiceLoaderModuleService(LogService.getLogger()));
+    XmlUtils.addNewNode(config, xmlEntity, new ServiceLoaderModuleService(LogService.getLogger()));
 
     nodes = XmlUtils.query(config, xPath, xPathContext);
     assertEquals(1, nodes.getLength());
@@ -278,7 +296,8 @@ public class XmlUtilsAddNewNodeJUnitTest {
   }
 
   /**
-   * Tests {@link XmlUtils#addNewNode(Document, XmlEntity)} with an {@link Extension} that does not
+   * Tests {@link XmlUtils#addNewNode(Document, XmlEntity, ModuleService)} with an {@link Extension}
+   * that does not
    * have a name or id attribute, <code>test:cache</code>. It should replace the existing
    * <code>test:cache</code> element.
    *
@@ -295,7 +314,8 @@ public class XmlUtilsAddNewNodeJUnitTest {
 
     final org.w3c.dom.Document changes =
         XmlUtils.createDocumentFromReader(new InputStreamReader(this.getClass().getResourceAsStream(
-            "XmlUtilsAddNewNodeJUnitTest.testAddNewNodeReplaceUnnamedExtension.xml")));
+            "XmlUtilsAddNewNodeJUnitTest.testAddNewNodeReplaceUnnamedExtension.xml")),
+            new ServiceLoaderModuleService(LogService.getLogger()));
     nodes = XmlUtils.query(changes, xPath, xPathContext);
     assertEquals(1, nodes.getLength());
     element = (Element) nodes.item(0);
@@ -303,8 +323,9 @@ public class XmlUtilsAddNewNodeJUnitTest {
     assertEquals(TEST_NAMESPACE, element.getNamespaceURI());
 
     final XmlEntity xmlEntity = XmlEntity.builder().withType("cache")
-        .withNamespace(TEST_PREFIX, TEST_NAMESPACE).withConfig(changes).build();
-    XmlUtils.addNewNode(config, xmlEntity);
+        .withNamespace(TEST_PREFIX, TEST_NAMESPACE).withConfig(changes)
+        .build(new ServiceLoaderModuleService(LogService.getLogger()));
+    XmlUtils.addNewNode(config, xmlEntity, new ServiceLoaderModuleService(LogService.getLogger()));
 
     nodes = XmlUtils.query(config, xPath, xPathContext);
     assertEquals(1, nodes.getLength());
@@ -330,12 +351,13 @@ public class XmlUtilsAddNewNodeJUnitTest {
     assertEquals(CacheXml.GEODE_NAMESPACE, element.getNamespaceURI());
 
     final Document changes = XmlUtils.createDocumentFromReader(new InputStreamReader(this.getClass()
-        .getResourceAsStream("XmlUtilsAddNewNodeJUnitTest.testDeleteNodeNamed.xml")));
+        .getResourceAsStream("XmlUtilsAddNewNodeJUnitTest.testDeleteNodeNamed.xml")),
+        new ServiceLoaderModuleService(LogService.getLogger()));
     nodes = XmlUtils.query(changes, xPath, xPathContext);
     assertEquals(0, nodes.getLength());
 
     final XmlEntity xmlEntity = XmlEntity.builder().withType("region").withAttribute("name", "r1")
-        .withConfig(changes).build();
+        .withConfig(changes).build(new ServiceLoaderModuleService(LogService.getLogger()));
     XmlUtils.deleteNode(config, xmlEntity);
 
     nodes = XmlUtils.query(config, xPath, xPathContext);
@@ -343,7 +365,8 @@ public class XmlUtilsAddNewNodeJUnitTest {
   }
 
   /**
-   * Tests {@link XmlUtils#addNewNode(Document, XmlEntity)} with {@link CacheXml} element that does
+   * Tests {@link XmlUtils#addNewNode(Document, XmlEntity, ModuleService)} with {@link CacheXml}
+   * element that does
    * not have a name or id attribute, <code>pdx</code>. It should remove the existing
    * <code>pdx</code> element.
    *
@@ -359,11 +382,14 @@ public class XmlUtilsAddNewNodeJUnitTest {
     assertEquals(CacheXml.GEODE_NAMESPACE, element.getNamespaceURI());
 
     final Document changes = XmlUtils.createDocumentFromReader(new InputStreamReader(this.getClass()
-        .getResourceAsStream("XmlUtilsAddNewNodeJUnitTest.testDeleteNodeUnnamed.xml")));
+        .getResourceAsStream("XmlUtilsAddNewNodeJUnitTest.testDeleteNodeUnnamed.xml")),
+        new ServiceLoaderModuleService(LogService.getLogger()));
     nodes = XmlUtils.query(changes, xPath, xPathContext);
     assertEquals(0, nodes.getLength());
 
-    final XmlEntity xmlEntity = XmlEntity.builder().withType("pdx").withConfig(changes).build();
+    final XmlEntity xmlEntity =
+        XmlEntity.builder().withType("pdx").withConfig(changes)
+            .build(new ServiceLoaderModuleService(LogService.getLogger()));
     XmlUtils.deleteNode(config, xmlEntity);
 
     nodes = XmlUtils.query(config, xPath, xPathContext);
@@ -371,7 +397,8 @@ public class XmlUtilsAddNewNodeJUnitTest {
   }
 
   /**
-   * Tests {@link XmlUtils#addNewNode(Document, XmlEntity)} with an {@link Extension} that does not
+   * Tests {@link XmlUtils#addNewNode(Document, XmlEntity, ModuleService)} with an {@link Extension}
+   * that does not
    * have a name or id attribute, <code>test:cache</code>. It should remove the existing
    * <code>test:cache</code> element.
    *
@@ -387,12 +414,14 @@ public class XmlUtilsAddNewNodeJUnitTest {
     assertEquals(TEST_NAMESPACE, element.getNamespaceURI());
 
     final Document changes = XmlUtils.createDocumentFromReader(new InputStreamReader(this.getClass()
-        .getResourceAsStream("XmlUtilsAddNewNodeJUnitTest.testDeleteNodeUnnamedExtension.xml")));
+        .getResourceAsStream("XmlUtilsAddNewNodeJUnitTest.testDeleteNodeUnnamedExtension.xml")),
+        new ServiceLoaderModuleService(LogService.getLogger()));
     nodes = XmlUtils.query(changes, xPath, xPathContext);
     assertEquals(0, nodes.getLength());
 
     final XmlEntity xmlEntity = XmlEntity.builder().withType("cache")
-        .withNamespace(TEST_PREFIX, TEST_NAMESPACE).withConfig(changes).build();
+        .withNamespace(TEST_PREFIX, TEST_NAMESPACE).withConfig(changes)
+        .build(new ServiceLoaderModuleService(LogService.getLogger()));
     XmlUtils.deleteNode(config, xmlEntity);
 
     nodes = XmlUtils.query(config, xPath, xPathContext);
diff --git a/geode-core/src/main/java/org/apache/geode/admin/AdminDistributedSystemFactory.java b/geode-core/src/main/java/org/apache/geode/admin/AdminDistributedSystemFactory.java
index 7cfe0c9..b2dc855 100755
--- a/geode-core/src/main/java/org/apache/geode/admin/AdminDistributedSystemFactory.java
+++ b/geode-core/src/main/java/org/apache/geode/admin/AdminDistributedSystemFactory.java
@@ -24,6 +24,7 @@ import org.apache.geode.distributed.internal.DistributionConfig;
 import org.apache.geode.distributed.internal.DistributionConfigImpl;
 import org.apache.geode.distributed.internal.InternalDistributedSystem;
 import org.apache.geode.internal.logging.LocalLogWriter;
+import org.apache.geode.services.module.ModuleService;
 
 /**
  * Factory for creating GemFire administration entities.
@@ -128,8 +129,9 @@ public class AdminDistributedSystemFactory {
    * @param config configuration definition of the system to administer
    * @return administrative interface for a distributed system
    */
-  public static AdminDistributedSystem getDistributedSystem(DistributedSystemConfig config) {
-    return new AdminDistributedSystemImpl((DistributedSystemConfigImpl) config);
+  public static AdminDistributedSystem getDistributedSystem(DistributedSystemConfig config,
+      ModuleService moduleService) {
+    return new AdminDistributedSystemImpl((DistributedSystemConfigImpl) config, moduleService);
   }
 
   /**
diff --git a/geode-core/src/main/java/org/apache/geode/admin/internal/AdminDistributedSystemImpl.java b/geode-core/src/main/java/org/apache/geode/admin/internal/AdminDistributedSystemImpl.java
index 66ff10f..5a5e1ab 100755
--- a/geode-core/src/main/java/org/apache/geode/admin/internal/AdminDistributedSystemImpl.java
+++ b/geode-core/src/main/java/org/apache/geode/admin/internal/AdminDistributedSystemImpl.java
@@ -100,6 +100,7 @@ import org.apache.geode.internal.util.concurrent.FutureResult;
 import org.apache.geode.logging.internal.LoggingSession;
 import org.apache.geode.logging.internal.NullLoggingSession;
 import org.apache.geode.logging.internal.log4j.api.LogService;
+import org.apache.geode.services.module.ModuleService;
 
 /**
  * Represents a GemFire distributed system for remote administration/management.
@@ -204,7 +205,8 @@ public class AdminDistributedSystemImpl implements org.apache.geode.admin.AdminD
    *
    * @param config configuration defining this distributed system
    */
-  public AdminDistributedSystemImpl(DistributedSystemConfigImpl config) {
+  public AdminDistributedSystemImpl(DistributedSystemConfigImpl config,
+      ModuleService moduleService) {
     loggingSession = createLoggingSession();
 
     // init from config...
@@ -235,7 +237,7 @@ public class AdminDistributedSystemImpl implements org.apache.geode.admin.AdminD
       this.logWriter = LogWriterFactory.createLogWriterLogger(this.config.createLogConfig(), false);
       if (!Boolean.getBoolean(InternalLocator.INHIBIT_DM_BANNER)) {
         // LOG: changed statement from config to info
-        this.logWriter.info(new Banner().getString());
+        this.logWriter.info(new Banner(moduleService).getString());
       } else {
         logger.debug("skipping banner - " + InternalLocator.INHIBIT_DM_BANNER + " is set to true");
       }
diff --git a/geode-core/src/main/java/org/apache/geode/admin/jmx/AgentFactory.java b/geode-core/src/main/java/org/apache/geode/admin/jmx/AgentFactory.java
index b4c8fc7..c3b018e 100644
--- a/geode-core/src/main/java/org/apache/geode/admin/jmx/AgentFactory.java
+++ b/geode-core/src/main/java/org/apache/geode/admin/jmx/AgentFactory.java
@@ -17,6 +17,7 @@ package org.apache.geode.admin.jmx;
 import org.apache.geode.admin.AdminException;
 import org.apache.geode.admin.jmx.internal.AgentConfigImpl;
 import org.apache.geode.admin.jmx.internal.AgentImpl;
+import org.apache.geode.services.module.ModuleService;
 
 /**
  * A factory class that creates JMX administration entities.
@@ -40,8 +41,9 @@ public class AgentFactory {
    *
    * @see Agent#start
    */
-  public static Agent getAgent(AgentConfig config) throws AdminException {
-    return new AgentImpl((AgentConfigImpl) config);
+  public static Agent getAgent(AgentConfig config, ModuleService moduleService)
+      throws AdminException {
+    return new AgentImpl((AgentConfigImpl) config, moduleService);
   }
 
 }
diff --git a/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/AdminDistributedSystemJmxImpl.java b/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/AdminDistributedSystemJmxImpl.java
index 931ba18..a4631c2 100755
--- a/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/AdminDistributedSystemJmxImpl.java
+++ b/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/AdminDistributedSystemJmxImpl.java
@@ -89,6 +89,7 @@ import org.apache.geode.internal.admin.StatAlertDefinition;
 import org.apache.geode.internal.admin.remote.UpdateAlertDefinitionMessage;
 import org.apache.geode.internal.logging.InternalLogWriter;
 import org.apache.geode.logging.internal.log4j.api.LogService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 import org.apache.geode.util.internal.GeodeGlossary;
 
 /**
@@ -140,7 +141,7 @@ public class AdminDistributedSystemJmxImpl extends AdminDistributedSystemImpl
    */
   public AdminDistributedSystemJmxImpl(AgentConfigImpl config)
       throws org.apache.geode.admin.AdminException {
-    super(config);
+    super(config, new ServiceLoaderModuleService(LogService.getLogger()));
     this.mbeanName = "GemFire:type=AdminDistributedSystem,id="
         + MBeanUtil.makeCompliantMBeanNameProperty(getId());
     this.objectName = MBeanUtil.createMBean(this);
diff --git a/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/AgentImpl.java b/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/AgentImpl.java
index 37b25e7..182ad7b 100644
--- a/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/AgentImpl.java
+++ b/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/AgentImpl.java
@@ -70,6 +70,8 @@ import org.apache.geode.logging.internal.log4j.api.LogService;
 import org.apache.geode.logging.internal.spi.LogConfig;
 import org.apache.geode.logging.internal.spi.LogConfigListener;
 import org.apache.geode.logging.internal.spi.LogConfigSupplier;
+import org.apache.geode.services.module.ModuleService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 
 /**
  * The GemFire JMX Agent provides the ability to administrate one GemFire distributed system via
@@ -185,8 +187,9 @@ public class AgentImpl implements org.apache.geode.admin.jmx.Agent,
    * @throws org.apache.geode.admin.AdminException TODO-javadocs
    * @throws IllegalArgumentException if agentConfig is null
    */
-  public AgentImpl(AgentConfigImpl agentConfig) throws AdminException, IllegalArgumentException {
-    loggingSession = LoggingSession.create();
+  public AgentImpl(AgentConfigImpl agentConfig, ModuleService moduleService)
+      throws AdminException, IllegalArgumentException {
+    loggingSession = LoggingSession.create(moduleService);
 
     shutdownHook = new LoggingThread("Shutdown", false, () -> disconnectFromSystem());
     addShutdownHook();
@@ -1045,7 +1048,8 @@ public class AgentImpl implements org.apache.geode.admin.jmx.Agent,
     }
 
     try {
-      Agent agent = AgentFactory.getAgent(ac);
+      Agent agent =
+          AgentFactory.getAgent(ac, new ServiceLoaderModuleService(LogService.getLogger()));
       agent.start();
 
     } catch (VirtualMachineError err) {
diff --git a/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/AgentLauncher.java b/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/AgentLauncher.java
index b18deda..d9c64ef 100644
--- a/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/AgentLauncher.java
+++ b/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/AgentLauncher.java
@@ -52,6 +52,8 @@ import org.apache.geode.internal.util.JavaCommandBuilder;
 import org.apache.geode.logging.internal.OSProcess;
 import org.apache.geode.logging.internal.executors.LoggingThread;
 import org.apache.geode.logging.internal.log4j.api.LogService;
+import org.apache.geode.services.module.ModuleService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 
 /**
  * A command line utility that is responsible for administering a stand-alone GemFire JMX
@@ -363,7 +365,9 @@ public class AgentLauncher {
 
     writeStatus(createStatus(this.basename, STARTING, OSProcess.getId()));
 
-    final Agent agent = createAgent((Properties) options.get(AGENT_PROPS));
+    final Agent agent =
+        createAgent((Properties) options.get(AGENT_PROPS), new ServiceLoaderModuleService(
+            LogService.getLogger()));
 
     final Thread thread = createAgentProcessThread(agent);
     thread.start();
@@ -372,7 +376,8 @@ public class AgentLauncher {
     pollAgentForPendingShutdown(agent);
   }
 
-  private Agent createAgent(final Properties props) throws IOException, AdminException {
+  private Agent createAgent(final Properties props, ModuleService moduleService)
+      throws IOException, AdminException {
     ClusterDistributionManager.setIsDedicatedAdminVM(true);
     SystemFailure.setExitOK(true);
 
@@ -387,7 +392,7 @@ public class AgentLauncher {
     OSProcess.redirectOutput(new File(config.getLogFile())); // redirect output to the configured
                                                              // log file
 
-    return AgentFactory.getAgent(config);
+    return AgentFactory.getAgent(config, moduleService);
   }
 
   private UncaughtExceptionHandler createUncaughtExceptionHandler() {
diff --git a/geode-core/src/main/java/org/apache/geode/cache/CacheFactory.java b/geode-core/src/main/java/org/apache/geode/cache/CacheFactory.java
index 2179a94..4d5eb0a 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/CacheFactory.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/CacheFactory.java
@@ -25,12 +25,15 @@ import org.apache.geode.distributed.DistributedSystem;
 import org.apache.geode.internal.GemFireVersion;
 import org.apache.geode.internal.cache.CacheFactoryStatics;
 import org.apache.geode.internal.cache.InternalCacheBuilder;
+import org.apache.geode.logging.internal.log4j.api.LogService;
 import org.apache.geode.pdx.PdxInstance;
 import org.apache.geode.pdx.PdxSerializer;
 import org.apache.geode.security.AuthenticationFailedException;
 import org.apache.geode.security.AuthenticationRequiredException;
 import org.apache.geode.security.PostProcessor;
 import org.apache.geode.security.SecurityManager;
+import org.apache.geode.services.module.ModuleService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 
 /**
  * Factory class used to create the singleton {@link Cache cache} and connect to the GemFire
@@ -109,7 +112,8 @@ public class CacheFactory {
    * @since GemFire 6.5
    */
   public CacheFactory(Properties props) {
-    internalCacheBuilder = new InternalCacheBuilder(props);
+    internalCacheBuilder = new InternalCacheBuilder(props, new ServiceLoaderModuleService(
+        LogService.getLogger()));
   }
 
   /**
@@ -349,7 +353,8 @@ public class CacheFactory {
   @Deprecated
   public static Cache create(DistributedSystem system) throws CacheExistsException,
       TimeoutException, CacheWriterException, GatewayException, RegionExistsException {
-    return CacheFactoryStatics.create(system);
+    return CacheFactoryStatics.create(system,
+        new ServiceLoaderModuleService(LogService.getLogger()));
   }
 
   /**
@@ -404,4 +409,9 @@ public class CacheFactory {
   public static String getVersion() {
     return GemFireVersion.getGemFireVersion();
   }
+
+  public CacheFactory setModuleService(ModuleService moduleService) {
+    internalCacheBuilder.setModuleService(moduleService);
+    return this;
+  }
 }
diff --git a/geode-core/src/main/java/org/apache/geode/cache/client/ClientCacheFactory.java b/geode-core/src/main/java/org/apache/geode/cache/client/ClientCacheFactory.java
index ffaced9..2b9ec8e 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/client/ClientCacheFactory.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/client/ClientCacheFactory.java
@@ -34,6 +34,7 @@ import org.apache.geode.internal.GemFireVersion;
 import org.apache.geode.internal.cache.CacheConfig;
 import org.apache.geode.internal.cache.GemFireCacheImpl;
 import org.apache.geode.internal.cache.InternalCacheBuilder;
+import org.apache.geode.logging.internal.log4j.api.LogService;
 import org.apache.geode.metrics.internal.InternalDistributedSystemMetricsService;
 import org.apache.geode.metrics.internal.MetricsService;
 import org.apache.geode.net.SSLParameterExtension;
@@ -41,6 +42,7 @@ import org.apache.geode.pdx.PdxInstance;
 import org.apache.geode.pdx.PdxSerializer;
 import org.apache.geode.security.AuthenticationFailedException;
 import org.apache.geode.security.AuthenticationRequiredException;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 
 /**
  * Factory class used to create the singleton {@link ClientCache client cache} and connect to one or
@@ -267,10 +269,11 @@ public class ClientCacheFactory {
         return instance;
       } else {
 
-        return (InternalClientCache) new InternalCacheBuilder(cacheConfig)
-            .setIsClient(true)
-            .setPoolFactory(pf)
-            .create(system);
+        return (InternalClientCache) new InternalCacheBuilder(cacheConfig,
+            new ServiceLoaderModuleService(LogService.getLogger()))
+                .setIsClient(true)
+                .setPoolFactory(pf)
+                .create(system);
       }
     }
   }
@@ -279,7 +282,8 @@ public class ClientCacheFactory {
     MetricsService.Builder metricsServiceBuilder =
         new InternalDistributedSystemMetricsService.Builder()
             .setIsClient(true);
-    return InternalDistributedSystem.connectInternal(dsProps, null, metricsServiceBuilder);
+    return InternalDistributedSystem.connectInternal(dsProps, null, metricsServiceBuilder,
+        new ServiceLoaderModuleService(LogService.getLogger()));
   }
 
   private PoolFactory getPoolFactory() {
diff --git a/geode-core/src/main/java/org/apache/geode/cache/query/internal/QueryConfigurationServiceImpl.java b/geode-core/src/main/java/org/apache/geode/cache/query/internal/QueryConfigurationServiceImpl.java
index 6e769f8..f4d2ec9 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/query/internal/QueryConfigurationServiceImpl.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/query/internal/QueryConfigurationServiceImpl.java
@@ -38,6 +38,7 @@ import org.apache.geode.internal.cache.CacheService;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.logging.internal.log4j.api.LogService;
 import org.apache.geode.management.internal.beans.CacheServiceMBeanBase;
+import org.apache.geode.services.module.ModuleService;
 
 public class QueryConfigurationServiceImpl implements QueryConfigurationService {
   private static final Logger logger = LogService.getLogger();
@@ -84,7 +85,7 @@ public class QueryConfigurationServiceImpl implements QueryConfigurationService
   }
 
   @Override
-  public boolean init(Cache cache) {
+  public boolean init(Cache cache, ModuleService moduleService) {
     if (cache == null) {
       throw new IllegalArgumentException(NULL_CACHE_ERROR_MESSAGE);
     }
diff --git a/geode-core/src/main/java/org/apache/geode/cache/query/internal/cq/CqServiceProvider.java b/geode-core/src/main/java/org/apache/geode/cache/query/internal/cq/CqServiceProvider.java
index e61c27b..03ee7a4 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/query/internal/cq/CqServiceProvider.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/query/internal/cq/CqServiceProvider.java
@@ -16,20 +16,22 @@ package org.apache.geode.cache.query.internal.cq;
 
 import java.io.DataInput;
 import java.io.IOException;
-import java.util.Iterator;
-import java.util.ServiceLoader;
+import java.util.Set;
 
 import org.apache.geode.annotations.Immutable;
 import org.apache.geode.annotations.internal.MutableForTesting;
 import org.apache.geode.cache.query.internal.cq.spi.CqServiceFactory;
 import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.services.module.ModuleService;
+import org.apache.geode.services.result.ModuleServiceResult;
 import org.apache.geode.util.internal.GeodeGlossary;
 
 public class CqServiceProvider {
 
-  @Immutable
-  private static final CqServiceFactory factory;
-
+  /**
+   * A debug flag used for testing vMotion during CQ registration
+   */
+  public static final boolean VMOTION_DURING_CQ_REGISTRATION_FLAG = false;
   /**
    * System property to maintain the CQ event references for optimizing the updates. This will allow
    * running the CQ query only once during update events.
@@ -37,24 +39,29 @@ public class CqServiceProvider {
   @MutableForTesting
   public static boolean MAINTAIN_KEYS = Boolean
       .parseBoolean(System.getProperty(GeodeGlossary.GEMFIRE_PREFIX + "cq.MAINTAIN_KEYS", "true"));
+  @Immutable
+  private static CqServiceFactory factory;
 
-  /**
-   * A debug flag used for testing vMotion during CQ registration
-   */
-  public static final boolean VMOTION_DURING_CQ_REGISTRATION_FLAG = false;
+  private CqServiceProvider() {}
 
-  static {
-    ServiceLoader<CqServiceFactory> loader = ServiceLoader.load(CqServiceFactory.class);
-    Iterator<CqServiceFactory> itr = loader.iterator();
-    if (!itr.hasNext()) {
-      factory = null;
-    } else {
-      factory = itr.next();
-      factory.initialize();
+  private static void setup(ModuleService moduleService) {
+    if (factory == null) {
+      ModuleServiceResult<Set<CqServiceFactory>> loadServiceResult =
+          moduleService.loadService(CqServiceFactory.class);
+      if (loadServiceResult.isSuccessful()) {
+        for (CqServiceFactory cqServiceFactory : loadServiceResult.getMessage()) {
+          factory = cqServiceFactory;
+          factory.initialize();
+          break;
+        }
+      } else {
+        factory = null;
+      }
     }
   }
 
-  public static CqService create(InternalCache cache) {
+  public static synchronized CqService create(InternalCache cache, ModuleService moduleService) {
+    setup(moduleService);
     if (factory == null) {
       return new MissingCqService();
     }
@@ -69,6 +76,4 @@ public class CqServiceProvider {
       return factory.readCqQuery(in);
     }
   }
-
-  private CqServiceProvider() {}
 }
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/DistributedSystem.java b/geode-core/src/main/java/org/apache/geode/distributed/DistributedSystem.java
index 303abc1..60d0746 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/DistributedSystem.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/DistributedSystem.java
@@ -42,7 +42,9 @@ import org.apache.geode.internal.Assert;
 import org.apache.geode.internal.ClassPathLoader;
 import org.apache.geode.internal.tcp.ConnectionTable;
 import org.apache.geode.internal.util.IOUtils;
+import org.apache.geode.logging.internal.log4j.api.LogService;
 import org.apache.geode.metrics.internal.InternalDistributedSystemMetricsService;
+import org.apache.geode.services.module.impl.ServiceLoaderModuleService;
 import org.apache.geode.util.internal.GeodeGlossary;
 
 /**
@@ -157,7 +159,8 @@ public abstract class DistributedSystem implements StatisticsFactory {
    */
   public static DistributedSystem connect(Properties config) {
     return InternalDistributedSystem.connectInternal(config, null,
-        new InternalDistributedSystemMetricsService.Builder());
+        new InternalDistributedSystemMetricsService.Builder(),
... 16487 lines suppressed ...


[geode] 04/08: GEODE-8137 - Implement loadService. (#5136)

Posted by ud...@apache.org.
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 979bb4e80508bd00f6b62e98e9fb02cfcca76934
Author: Patrick Johnson <pj...@pivotal.io>
AuthorDate: Fri May 22 07:31:59 2020 -0700

    GEODE-8137 - Implement loadService. (#5136)
---
 .../integrationTest/resources/assembly_content.txt |  2 +-
 .../geode/services/module/ModuleService.java       | 18 ++++
 geode-modules/build.gradle                         |  3 +
 .../services/module/impl/GeodeModuleLoader.java    |  2 +-
 ...uleService.java => JBossModuleServiceImpl.java} | 57 +++++++++++--
 .../java/org/apache/geode/InvalidService.java}     |  2 +-
 .../java/org/apache/geode/TestService.java}        |  3 +-
 ...ceTest.java => JBossModuleServiceImplTest.java} | 95 +++++++++++++++++++++-
 .../module1/java/org/apache/geode/Module1.java     |  6 +-
 .../META-INF/services/org.apache.geode.TestService |  1 +
 .../apache/geode}/Module2.java                     |  6 +-
 .../META-INF/services/org.apache.geode.TestService |  1 +
 12 files changed, 182 insertions(+), 14 deletions(-)

diff --git a/geode-assembly/src/integrationTest/resources/assembly_content.txt b/geode-assembly/src/integrationTest/resources/assembly_content.txt
index 9c4051a..3e21fb9 100644
--- a/geode-assembly/src/integrationTest/resources/assembly_content.txt
+++ b/geode-assembly/src/integrationTest/resources/assembly_content.txt
@@ -978,7 +978,7 @@ javadoc/org/apache/geode/services/module/ModuleDescriptor.Builder.html
 javadoc/org/apache/geode/services/module/ModuleDescriptor.html
 javadoc/org/apache/geode/services/module/ModuleService.html
 javadoc/org/apache/geode/services/module/impl/GeodeModuleLoader.html
-javadoc/org/apache/geode/services/module/impl/JBossModuleService.html
+javadoc/org/apache/geode/services/module/impl/JBossModuleServiceImpl.html
 javadoc/org/apache/geode/services/module/impl/package-frame.html
 javadoc/org/apache/geode/services/module/impl/package-summary.html
 javadoc/org/apache/geode/services/module/impl/package-tree.html
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 cd295c0..81361be 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
@@ -15,6 +15,8 @@
 
 package org.apache.geode.services.module;
 
+import java.util.List;
+
 import org.apache.geode.annotations.Experimental;
 
 /**
@@ -33,4 +35,20 @@ public interface ModuleService {
    * @return true on success, false if the module could not be loaded.
    */
   boolean loadModule(ModuleDescriptor moduleDescriptor);
+
+  /**
+   * Unloads a previously loaded module.
+   *
+   * @param moduleName name of the module to be unloaded.
+   * @return true on success, false if the module could not be unloaded.
+   */
+  boolean unloadModule(String moduleName);
+
+  /**
+   * Loads and returns a service instance for an interface.
+   *
+   * @param service interface type to load and instantiate an implementation of.
+   * @return An instance of an implementation of service
+   */
+  <T> List<T> loadService(Class<T> service);
 }
diff --git a/geode-modules/build.gradle b/geode-modules/build.gradle
index 319c0bd..17572a8 100644
--- a/geode-modules/build.gradle
+++ b/geode-modules/build.gradle
@@ -94,4 +94,7 @@ dependencies {
 
     implementation('org.apache.logging.log4j:log4j-core')
     compile('org.jboss.modules:jboss-modules')
+
+    module1Compile(sourceSets.test.output)
+    module2Compile(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 913df0c..a9d65c9 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
@@ -27,7 +27,7 @@ import org.jboss.modules.ModuleSpec;
 import org.apache.geode.annotations.Experimental;
 
 /**
- * {@link ModuleLoader} for use by {@link JBossModuleService}.
+ * {@link ModuleLoader} for use by {@link JBossModuleServiceImpl}.
  */
 @Experimental
 public class GeodeModuleLoader extends DelegatingModuleLoader {
diff --git a/geode-modules/src/main/java/org/apache/geode/services/module/impl/JBossModuleService.java b/geode-modules/src/main/java/org/apache/geode/services/module/impl/JBossModuleServiceImpl.java
similarity index 68%
rename from geode-modules/src/main/java/org/apache/geode/services/module/impl/JBossModuleService.java
rename to geode-modules/src/main/java/org/apache/geode/services/module/impl/JBossModuleServiceImpl.java
index 9715709..c7be4c5 100644
--- a/geode-modules/src/main/java/org/apache/geode/services/module/impl/JBossModuleService.java
+++ b/geode-modules/src/main/java/org/apache/geode/services/module/impl/JBossModuleServiceImpl.java
@@ -17,15 +17,19 @@ package org.apache.geode.services.module.impl;
 
 import java.io.IOException;
 import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Map;
 import java.util.jar.JarFile;
 
 import org.apache.logging.log4j.Logger;
+import org.jboss.modules.DependencySpec;
 import org.jboss.modules.LocalDependencySpecBuilder;
 import org.jboss.modules.Module;
 import org.jboss.modules.ModuleDependencySpecBuilder;
 import org.jboss.modules.ModuleLoadException;
 import org.jboss.modules.ModuleSpec;
+import org.jboss.modules.PathUtils;
 import org.jboss.modules.ResourceLoader;
 import org.jboss.modules.ResourceLoaderSpec;
 import org.jboss.modules.ResourceLoaders;
@@ -40,7 +44,7 @@ import org.apache.geode.services.module.ModuleService;
  * Implementation of {@link ModuleService} using JBoss-Modules.
  */
 @Experimental
-public class JBossModuleService implements ModuleService {
+public class JBossModuleServiceImpl implements ModuleService {
 
   private final Map<String, Module> modules = new HashMap<>();
 
@@ -48,11 +52,11 @@ public class JBossModuleService implements ModuleService {
 
   private final Logger logger;
 
-  public JBossModuleService() {
+  public JBossModuleServiceImpl() {
     this(LogService.getLogger());
   }
 
-  public JBossModuleService(Logger logger) {
+  public JBossModuleServiceImpl(Logger logger) {
     this.logger = logger;
   }
 
@@ -70,6 +74,7 @@ public class JBossModuleService implements ModuleService {
       return false;
     }
 
+    // Setting up new module.
     ModuleSpec.Builder builder = ModuleSpec.build(moduleDescriptor.getVersionedName());
     builder.setVersion(Version.parse(moduleDescriptor.getVersion()));
     builder.addDependency(new LocalDependencySpecBuilder()
@@ -77,13 +82,17 @@ public class JBossModuleService implements ModuleService {
         .setExport(true)
         .build());
 
+    // Add dependencies to the module.
     moduleDescriptor.getDependedOnModules().forEach(dependency -> {
       logger.debug(String.format("Adding dependency on module %s", dependency));
       builder.addDependency(new ModuleDependencySpecBuilder()
+          .setExport(true)
+          .setImportServices(true)
           .setName(dependency)
           .build());
     });
 
+    // Add resources to the module.
     try {
       for (String source : moduleDescriptor.getSources()) {
         logger.debug(String.format("Adding resource %s to module", source));
@@ -92,18 +101,24 @@ public class JBossModuleService implements ModuleService {
         builder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec(resourceLoader));
       }
     } catch (IOException e) {
-      logger.error(e);
+      logger.error(e.getMessage(), e);
       return false;
     }
 
+    // Add dependency on the system classloader so modules can access classes that aren't in
+    // modules.
+    builder.addDependency(DependencySpec.createSystemDependencySpec(PathUtils.getPathSet(null)));
+
+    // Build and register the ModuleSpec
     ModuleSpec moduleSpec = builder.create();
     moduleLoader.addModuleSpec(moduleSpec);
 
+    // Load the module and add it to the modules map.
     try {
       modules.put(moduleDescriptor.getVersionedName(),
           moduleLoader.loadModule(moduleSpec.getName()));
     } catch (ModuleLoadException e) {
-      logger.error(e);
+      logger.error(e.getMessage(), e);
       return false;
     }
 
@@ -112,4 +127,36 @@ public class JBossModuleService implements ModuleService {
 
     return true;
   }
+
+  @Override
+  public boolean unloadModule(String moduleName) {
+    return false;
+  }
+
+  @Override
+  public <T> List<T> loadService(Class<T> service) {
+    List<T> serviceImpls = new LinkedList<>();
+
+    // Iterate over all the modules looking for implementations of service.
+    modules.values().forEach((module) -> {
+      module.loadService(service).forEach((impl) -> {
+        // Check if class is already loaded.
+        // Modules with dependencies can cause duplicates without this check.
+        boolean duplicate = false;
+        for (T serviceImpl : serviceImpls) {
+          if (serviceImpl.getClass() == impl.getClass()) {
+            duplicate = true;
+            break;
+          }
+        }
+
+        // If impl is not a duplicate, add it to the list to return.
+        if (!duplicate) {
+          serviceImpls.add(impl);
+        }
+      });
+    });
+
+    return serviceImpls;
+  }
 }
diff --git a/geode-modules/src/testModules/module2/java/org.apache.geode/Module2.java b/geode-modules/src/test/java/org/apache/geode/InvalidService.java
similarity index 96%
copy from geode-modules/src/testModules/module2/java/org.apache.geode/Module2.java
copy to geode-modules/src/test/java/org/apache/geode/InvalidService.java
index 9cbac0f..f6deaeb 100644
--- a/geode-modules/src/testModules/module2/java/org.apache.geode/Module2.java
+++ b/geode-modules/src/test/java/org/apache/geode/InvalidService.java
@@ -15,5 +15,5 @@
 
 package org.apache.geode;
 
-public class Module2 {
+public interface InvalidService {
 }
diff --git a/geode-modules/src/testModules/module1/java/org/apache/geode/Module1.java b/geode-modules/src/test/java/org/apache/geode/TestService.java
similarity index 94%
copy from geode-modules/src/testModules/module1/java/org/apache/geode/Module1.java
copy to geode-modules/src/test/java/org/apache/geode/TestService.java
index 684a71c..55b40e6 100644
--- a/geode-modules/src/testModules/module1/java/org/apache/geode/Module1.java
+++ b/geode-modules/src/test/java/org/apache/geode/TestService.java
@@ -15,5 +15,6 @@
 
 package org.apache.geode;
 
-public class Module1 {
+public interface TestService {
+  String sayHello();
 }
diff --git a/geode-modules/src/test/java/org/apache/geode/services/module/impl/JBossModuleServiceTest.java b/geode-modules/src/test/java/org/apache/geode/services/module/impl/JBossModuleServiceImplTest.java
similarity index 82%
rename from geode-modules/src/test/java/org/apache/geode/services/module/impl/JBossModuleServiceTest.java
rename to geode-modules/src/test/java/org/apache/geode/services/module/impl/JBossModuleServiceImplTest.java
index bca62af..38bf0b3 100644
--- a/geode-modules/src/test/java/org/apache/geode/services/module/impl/JBossModuleServiceTest.java
+++ b/geode-modules/src/test/java/org/apache/geode/services/module/impl/JBossModuleServiceImplTest.java
@@ -18,14 +18,18 @@ package org.apache.geode.services.module.impl;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
+import java.util.List;
+
 import org.jboss.modules.Module;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
+import org.apache.geode.InvalidService;
+import org.apache.geode.TestService;
 import org.apache.geode.services.module.ModuleDescriptor;
 
-public class JBossModuleServiceTest {
+public class JBossModuleServiceImplTest {
 
   private static final String MODULE1_PATH =
       System.getProperty("user.dir") + "/../libs/module1.jar";
@@ -36,11 +40,14 @@ public class JBossModuleServiceTest {
   private static final String MODULE4_PATH =
       System.getProperty("user.dir") + "/../libs/module4.jar";
 
-  private JBossModuleService moduleService;
+  private static final String MODULE1_MESSAGE = "Hello from Module1!";
+  private static final String MODULE2_MESSAGE = "Hello from Module2!";
+
+  private JBossModuleServiceImpl moduleService;
 
   @Before
   public void setup() {
-    moduleService = new JBossModuleService();
+    moduleService = new JBossModuleServiceImpl();
   }
 
   @After
@@ -399,4 +406,86 @@ public class JBossModuleServiceTest {
     assertThat(module2).isNotNull();
     assertThat(module2.getName()).isEqualTo(module2Descriptor.getVersionedName());
   }
+
+  @Test
+  public void loadServiceNoModulesLoaded() {
+    assertThat(moduleService.loadService(TestService.class)).isEmpty();
+  }
+
+  @Test
+  public void loadServiceNoModulesImplementService() {
+    assertThat(moduleService.loadService(InvalidService.class)).isEmpty();
+  }
+
+  @Test
+  public void loadServiceFromSingleModule() {
+    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
+        .fromSources(MODULE1_PATH)
+        .build();
+    moduleService.loadModule(module1Descriptor);
+
+    List<TestService> serviceList = moduleService.loadService(TestService.class);
+    assertThat(serviceList.size()).isEqualTo(1);
+    assertThat(serviceList.get(0).sayHello()).isEqualTo(MODULE1_MESSAGE);
+  }
+
+  @Test
+  public void loadServicesFromMultipleModules() {
+    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
+        .fromSources(MODULE1_PATH)
+        .build();
+    ModuleDescriptor module2Descriptor = new ModuleDescriptor.Builder("module2", "1.0")
+        .fromSources(MODULE2_PATH)
+        .build();
+    moduleService.loadModule(module1Descriptor);
+    moduleService.loadModule(module2Descriptor);
+
+    List<TestService> serviceList = moduleService.loadService(TestService.class);
+    assertThat(serviceList.size()).isEqualTo(2);
+    assertThat(serviceList.stream().map(TestService::sayHello)).contains(MODULE1_MESSAGE,
+        MODULE2_MESSAGE);
+  }
+
+  @Test
+  public void loadServicesFromCompositeModule() {
+    ModuleDescriptor moduleDescriptor = new ModuleDescriptor.Builder("module1", "1.0")
+        .fromSources(MODULE1_PATH, MODULE2_PATH)
+        .build();
+    moduleService.loadModule(moduleDescriptor);
+
+    List<TestService> serviceList = moduleService.loadService(TestService.class);
+    assertThat(serviceList.size()).isEqualTo(2);
+    assertThat(serviceList.stream().map(TestService::sayHello)).contains(MODULE1_MESSAGE,
+        MODULE2_MESSAGE);
+  }
+
+  @Test
+  public void loadServiceFromModulesWithDependencies() {
+    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);
+
+    List<TestService> serviceList = moduleService.loadService(TestService.class);
+    assertThat(serviceList.size()).isEqualTo(2);
+    assertThat(serviceList.stream().map(TestService::sayHello)).contains(MODULE1_MESSAGE,
+        MODULE2_MESSAGE);
+  }
+
+  @Test
+  public void loadServiceFromModuleWithDuplicateContents() {
+    ModuleDescriptor module1Descriptor = new ModuleDescriptor.Builder("module1", "1.0")
+        .fromSources(MODULE1_PATH, MODULE1_PATH)
+        .build();
+    moduleService.loadModule(module1Descriptor);
+
+    List<TestService> serviceList = moduleService.loadService(TestService.class);
+    assertThat(serviceList.size()).isEqualTo(1);
+    assertThat(serviceList.get(0).sayHello()).isEqualTo(MODULE1_MESSAGE);
+  }
 }
diff --git a/geode-modules/src/testModules/module1/java/org/apache/geode/Module1.java b/geode-modules/src/testModules/module1/java/org/apache/geode/Module1.java
index 684a71c..0463781 100644
--- a/geode-modules/src/testModules/module1/java/org/apache/geode/Module1.java
+++ b/geode-modules/src/testModules/module1/java/org/apache/geode/Module1.java
@@ -15,5 +15,9 @@
 
 package org.apache.geode;
 
-public class Module1 {
+public class Module1 implements TestService {
+  @Override
+  public String sayHello() {
+    return "Hello from Module1!";
+  }
 }
diff --git a/geode-modules/src/testModules/module1/resources/META-INF/services/org.apache.geode.TestService b/geode-modules/src/testModules/module1/resources/META-INF/services/org.apache.geode.TestService
new file mode 100644
index 0000000..209c875
--- /dev/null
+++ b/geode-modules/src/testModules/module1/resources/META-INF/services/org.apache.geode.TestService
@@ -0,0 +1 @@
+org.apache.geode.Module1
\ No newline at end of file
diff --git a/geode-modules/src/testModules/module2/java/org.apache.geode/Module2.java b/geode-modules/src/testModules/module2/java/org/apache/geode/Module2.java
similarity index 86%
rename from geode-modules/src/testModules/module2/java/org.apache.geode/Module2.java
rename to geode-modules/src/testModules/module2/java/org/apache/geode/Module2.java
index 9cbac0f..1008bbd 100644
--- a/geode-modules/src/testModules/module2/java/org.apache.geode/Module2.java
+++ b/geode-modules/src/testModules/module2/java/org/apache/geode/Module2.java
@@ -15,5 +15,9 @@
 
 package org.apache.geode;
 
-public class Module2 {
+public class Module2 implements TestService {
+  @Override
+  public String sayHello() {
+    return "Hello from Module2!";
+  }
 }
diff --git a/geode-modules/src/testModules/module2/resources/META-INF/services/org.apache.geode.TestService b/geode-modules/src/testModules/module2/resources/META-INF/services/org.apache.geode.TestService
new file mode 100644
index 0000000..6e0cde8
--- /dev/null
+++ b/geode-modules/src/testModules/module2/resources/META-INF/services/org.apache.geode.TestService
@@ -0,0 +1 @@
+org.apache.geode.Module2
\ No newline at end of file


[geode] 02/08: GEODE-8041 - Create ManagementService interface. (#5062)

Posted by ud...@apache.org.
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 36d519bfbee6fcf6fcb47293f60cb784979ee151
Author: Patrick Johnson <pj...@pivotal.io>
AuthorDate: Wed May 6 14:50:06 2020 -0700

    GEODE-8041 - Create ManagementService interface. (#5062)
---
 .../services/management/ManagementService.java     | 39 ++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/geode-common-services/src/main/java/org/apache/geode/services/management/ManagementService.java b/geode-common-services/src/main/java/org/apache/geode/services/management/ManagementService.java
new file mode 100644
index 0000000..3e9ca47
--- /dev/null
+++ b/geode-common-services/src/main/java/org/apache/geode/services/management/ManagementService.java
@@ -0,0 +1,39 @@
+/*
+ * 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.geode.services.management;
+
+import java.util.Properties;
+
+import org.apache.geode.annotations.Experimental;
+import org.apache.geode.cache.Cache;
+
+/**
+ * Entry point for creating a cache and bootstrapping Geode using the BootstrappingService
+ *
+ * @since Geode 1.13.0
+ */
+@Experimental
+public interface ManagementService {
+
+  /**
+   * Creates a Geode Cache given some configuration.
+   *
+   * @param properties system properties to use when creating the Cache.
+   *
+   * @throws Exception is Cache cannot be created.
+   */
+  Cache createCache(Properties properties) throws Exception;
+}


[geode] 07/08: GEODE-8190: Clean up tests and automate Geode version. (#5243) (#5293)

Posted by ud...@apache.org.
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 627304aef3a68d3a6a646a18eded31118a318fb5
Author: Patrick Johnson <pj...@pivotal.io>
AuthorDate: Wed Jun 24 09:06:15 2020 -0700

    GEODE-8190: Clean up tests and automate Geode version. (#5243) (#5293)
---
 geode-modules/build.gradle                         |  6 +-
 ...esServiceImplWithPopulatedManifestFileTest.java | 13 +--
 .../jboss/modules/GeodeJarModuleFinderTest.java    | 95 +++++++++-------------
 3 files changed, 51 insertions(+), 63 deletions(-)

diff --git a/geode-modules/build.gradle b/geode-modules/build.gradle
index 853c638..bfbd6f5 100644
--- a/geode-modules/build.gradle
+++ b/geode-modules/build.gradle
@@ -47,7 +47,7 @@ sourceSets {
 
 def moduleTasks = []
 def moduleCopyTasks = []
-def geodeProjects = ['geode-common-services','geode-common']
+def geodeProjects = ['geode-common-services', 'geode-common']
 
 facets.each { thisConfig ->
     if (thisConfig.name.contains("WithoutManifest")) {
@@ -163,5 +163,7 @@ dependencies {
     module4WithManifestCompileOnly(sourceSets.test.output)
     module5WithManifestCompileOnly(sourceSets.test.output)
 
-    module1WithManifestCompile('org.springframework:spring-core')
+    module1WithManifestCompile('com.google.guava:guava:29.0-jre')
+
+    testCompile(project(":geode-core"))
 }
diff --git a/geode-modules/src/test/java/org/apache/geode/services/module/impl/JBossModulesServiceImplWithPopulatedManifestFileTest.java b/geode-modules/src/test/java/org/apache/geode/services/module/impl/JBossModulesServiceImplWithPopulatedManifestFileTest.java
index 145d7ac..8e5d43d 100644
--- a/geode-modules/src/test/java/org/apache/geode/services/module/impl/JBossModulesServiceImplWithPopulatedManifestFileTest.java
+++ b/geode-modules/src/test/java/org/apache/geode/services/module/impl/JBossModulesServiceImplWithPopulatedManifestFileTest.java
@@ -25,6 +25,7 @@ import org.apache.logging.log4j.LogManager;
 import org.junit.Before;
 import org.junit.Test;
 
+import org.apache.geode.internal.GemFireVersion;
 import org.apache.geode.services.module.ModuleDescriptor;
 import org.apache.geode.services.module.ModuleService;
 import org.apache.geode.services.result.ModuleServiceResult;
@@ -32,6 +33,8 @@ import org.apache.geode.services.result.impl.Failure;
 
 public class JBossModulesServiceImplWithPopulatedManifestFileTest {
 
+  private static String gemFireVersion = GemFireVersion.getGemFireVersion();
+
   private static final String MODULE1_PATH =
       System.getProperty("user.dir") + "/../libs/module1WithManifest-1.0.jar";
   private static final String MODULE2_PATH =
@@ -43,9 +46,9 @@ public class JBossModulesServiceImplWithPopulatedManifestFileTest {
   private static final String MODULE5_PATH =
       System.getProperty("user.dir") + "/../libs/module5WithManifest-1.0.jar";
   private static final String GEODE_COMMONS_SERVICES_PATH =
-      System.getProperty("user.dir") + "/../libs/geode-common-services-1.14.0-build.0.jar";
+      System.getProperty("user.dir") + "/../libs/geode-common-services-" + gemFireVersion + ".jar";
   private static final String GEODE_COMMONS_PATH =
-      System.getProperty("user.dir") + "/../libs/geode-common-1.14.0-build.0.jar";
+      System.getProperty("user.dir") + "/../libs/geode-common-" + gemFireVersion + ".jar";
 
   private ModuleService moduleService;
   private ModuleDescriptor geodeCommonsServiceDescriptor;
@@ -55,11 +58,11 @@ public class JBossModulesServiceImplWithPopulatedManifestFileTest {
   public void setup() {
     moduleService = new JBossModuleServiceImpl(LogManager.getLogger());
     geodeCommonsServiceDescriptor =
-        new ModuleDescriptor.Builder("geode-common-services-1.14.0-build.0")
+        new ModuleDescriptor.Builder("geode-common-services", gemFireVersion)
             .fromResourcePaths(GEODE_COMMONS_SERVICES_PATH)
             .build();
 
-    geodeCommonDescriptor = new ModuleDescriptor.Builder("geode-common-1.14.0-build.0")
+    geodeCommonDescriptor = new ModuleDescriptor.Builder("geode-common", gemFireVersion)
         .fromResourcePaths(GEODE_COMMONS_PATH)
         .build();
   }
@@ -84,7 +87,7 @@ public class JBossModulesServiceImplWithPopulatedManifestFileTest {
     loadModuleAndAssert(module2Descriptor);
 
     ModuleServiceResult<Map<String, Class<?>>> loadClassResult =
-        moduleService.loadClass("org.springframework.util.StringUtils");
+        moduleService.loadClass("com.google.common.base.Strings");
 
     assertThat(loadClassResult.isSuccessful()).isTrue();
 
diff --git a/geode-modules/src/test/java/org/jboss/modules/GeodeJarModuleFinderTest.java b/geode-modules/src/test/java/org/jboss/modules/GeodeJarModuleFinderTest.java
index 99846a4..6111a25 100644
--- a/geode-modules/src/test/java/org/jboss/modules/GeodeJarModuleFinderTest.java
+++ b/geode-modules/src/test/java/org/jboss/modules/GeodeJarModuleFinderTest.java
@@ -19,17 +19,20 @@ import static org.assertj.core.api.Assertions.assertThat;
 
 import java.io.IOException;
 import java.util.Arrays;
-import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
 
 import org.apache.logging.log4j.LogManager;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
+import org.apache.geode.internal.GemFireVersion;
 import org.apache.geode.services.module.ModuleDescriptor;
 
 public class GeodeJarModuleFinderTest {
 
+  private static String gemFireVersion = GemFireVersion.getGemFireVersion();
+
   private static final String MODULE1_PATH =
       System.getProperty("user.dir") + "/../libs/module1WithManifest-1.0.jar";
   private static final String MODULE2_PATH =
@@ -40,9 +43,26 @@ public class GeodeJarModuleFinderTest {
       System.getProperty("user.dir") + "/../libs/module4WithManifest-1.0.jar";
 
   private static final String GEODE_COMMONS_SERVICES_PATH =
-      System.getProperty("user.dir") + "/../libs/geode-common-services-1.14.0-build.0.jar";
+      System.getProperty("user.dir") + "/../libs/geode-common-services-" + gemFireVersion + ".jar";
   private static final String GEODE_COMMONS_PATH =
-      System.getProperty("user.dir") + "/../libs/geode-common-1.14.0-build.0.jar";
+      System.getProperty("user.dir") + "/../libs/geode-common-" + gemFireVersion + ".jar";
+
+  private static ModuleDescriptor geodeCommonsServiceDescriptor;
+
+  private static ModuleDescriptor geodeCommonDescriptor;
+
+  @BeforeClass
+  public static void setup() {
+    geodeCommonsServiceDescriptor =
+        new ModuleDescriptor.Builder("geode-common-services", gemFireVersion)
+            .fromResourcePaths(GEODE_COMMONS_SERVICES_PATH)
+            .build();
+
+    geodeCommonDescriptor =
+        new ModuleDescriptor.Builder("geode-common", gemFireVersion)
+            .fromResourcePaths(GEODE_COMMONS_PATH)
+            .build();
+  }
 
   @Test
   public void findModuleSimpleJar() throws IOException, ModuleLoadException {
@@ -56,23 +76,10 @@ public class GeodeJarModuleFinderTest {
 
     assertThat(moduleSpec.getName()).isEqualTo(moduleDescriptor.getName());
     assertThat(moduleSpec.getDependencies().length).isEqualTo(4);
-    String[] expectedDependencies = new String[] {"spring-core", "spring-jcl", "log4j-core",
-        "log4j-api", "jboss-modules", "module1WithManifest"};
-    ResourceLoaderSpec[] resourceLoaders = moduleSpec.getResourceLoaders();
-    assertThat(resourceLoaders.length).isEqualTo(expectedDependencies.length);
-    List<String> loadedResources = Arrays.stream(resourceLoaders)
-        .map(resourceLoaderSpec -> resourceLoaderSpec.getResourceLoader().getLocation().toString())
-        .collect(Collectors.toList());
-    for (String expectedDependency : expectedDependencies) {
-      boolean found = false;
-      for (String loadedResource : loadedResources) {
-        boolean contains = loadedResource.contains(expectedDependency);
-        if (contains) {
-          found = true;
-        }
-      }
-      assertThat(found).isTrue();
-    }
+    String[] expectedDependencies = new String[] {"log4j-core", "log4j-api", "jboss-modules",
+        "module1WithManifest", "guava", "failureaccess", "listenablefuture",
+        "jsr305", "checker-qual", "error_prone_annotations", "j2objc-annotations"};
+    assertModuleResourcesEqual(moduleSpec, expectedDependencies);
   }
 
   @Test
@@ -88,11 +95,12 @@ public class GeodeJarModuleFinderTest {
 
     assertThat(moduleSpec.getName()).isEqualTo(moduleDescriptor.getName());
     // This contain duplicate entries for 'geode-common-services'. This is because the underlying
-    // moduleBuilder does
-    // check for duplicates
+    // moduleBuilder does check for duplicates
     assertThat(moduleSpec.getDependencies().length).isEqualTo(5);
-    String[] expectedDependencies = new String[] {"spring-core", "spring-jcl", "log4j-core",
-        "log4j-api", "jboss-modules", "module1WithManifest", "module2WithManifest"};
+    String[] expectedDependencies = new String[] {"log4j-core", "log4j-api", "jboss-modules",
+        "module1WithManifest", "module2WithManifest", "guava", "failureaccess", "listenablefuture",
+        "jsr305", "checker-qual", "error_prone_annotations", "j2objc-annotations"};
+
     assertModuleResourcesEqual(moduleSpec, expectedDependencies);
   }
 
@@ -127,8 +135,9 @@ public class GeodeJarModuleFinderTest {
 
     assertThat(moduleSpec.getName()).isEqualTo(moduleDescriptor.getName());
     assertThat(moduleSpec.getDependencies().length).isEqualTo(5);
-    String[] expectedDependencies = new String[] {"spring-core", "spring-jcl", "log4j-core",
-        "log4j-api", "jboss-modules", "module1WithManifest"};
+    String[] expectedDependencies = new String[] {"log4j-core", "log4j-api", "jboss-modules",
+        "module1WithManifest", "guava", "failureaccess", "listenablefuture",
+        "jsr305", "checker-qual", "error_prone_annotations", "j2objc-annotations"};
     assertModuleResourcesEqual(moduleSpec, expectedDependencies);
   }
 
@@ -138,16 +147,6 @@ public class GeodeJarModuleFinderTest {
         new ModuleDescriptor.Builder("module1WithManifest", "1.0").fromResourcePaths(MODULE1_PATH)
             .build();
 
-    ModuleDescriptor geodeCommonsServiceDescriptor =
-        new ModuleDescriptor.Builder("geode-common-services-1.14.0-build.0")
-            .fromResourcePaths(GEODE_COMMONS_SERVICES_PATH)
-            .build();
-
-    ModuleDescriptor geodeCommonDescriptor =
-        new ModuleDescriptor.Builder("geode-common-1.14.0-build.0")
-            .fromResourcePaths(GEODE_COMMONS_PATH)
-            .build();
-
     ModuleLoader moduleLoader = new TestModuleLoader(Module.getSystemModuleLoader(),
         new ModuleFinder[] {
             new GeodeJarModuleFinder(LogManager.getLogger(),
@@ -168,16 +167,6 @@ public class GeodeJarModuleFinderTest {
             .fromResourcePaths(MODULE1_PATH, MODULE2_PATH)
             .build();
 
-    ModuleDescriptor geodeCommonsServiceDescriptor =
-        new ModuleDescriptor.Builder("geode-common-services-1.14.0-build.0")
-            .fromResourcePaths(GEODE_COMMONS_SERVICES_PATH)
-            .build();
-
-    ModuleDescriptor geodeCommonDescriptor =
-        new ModuleDescriptor.Builder("geode-common-1.14.0-build.0")
-            .fromResourcePaths(GEODE_COMMONS_PATH)
-            .build();
-
     ModuleLoader moduleLoader = new TestModuleLoader(Module.getSystemModuleLoader(),
         new ModuleFinder[] {
             new GeodeJarModuleFinder(LogManager.getLogger(), moduleDescriptor),
@@ -190,12 +179,6 @@ public class GeodeJarModuleFinderTest {
 
   @Test
   public void loadJarFileWithDependencies() throws IOException, ModuleLoadException {
-    ModuleDescriptor commonServices =
-        new ModuleDescriptor.Builder("geode-common-services", "1.14.0-build.0")
-            .fromResourcePaths(GEODE_COMMONS_SERVICES_PATH).build();
-
-    ModuleDescriptor geodeCommon = new ModuleDescriptor.Builder("geode-common", "1.14.0-build.0")
-        .fromResourcePaths(GEODE_COMMONS_PATH).build();
 
     ModuleDescriptor module1Descriptor =
         new ModuleDescriptor.Builder("module1WithManifest", "1.0").fromResourcePaths(MODULE1_PATH)
@@ -208,15 +191,15 @@ public class GeodeJarModuleFinderTest {
 
     ModuleLoader moduleLoader = new TestModuleLoader(Module.getSystemModuleLoader(),
         new ModuleFinder[] {
-            new GeodeJarModuleFinder(LogManager.getLogger(), geodeCommon),
-            new GeodeJarModuleFinder(LogManager.getLogger(), commonServices),
+            new GeodeJarModuleFinder(LogManager.getLogger(), geodeCommonDescriptor),
+            new GeodeJarModuleFinder(LogManager.getLogger(), geodeCommonsServiceDescriptor),
             new GeodeJarModuleFinder(LogManager.getLogger(),
                 module1Descriptor),
             new GeodeJarModuleFinder(LogManager.getLogger(), module2Descriptor)
         });
 
-    assertThat(moduleLoader.loadModule(geodeCommon.getName())).isNotNull();
-    assertThat(moduleLoader.loadModule(commonServices.getName())).isNotNull();
+    assertThat(moduleLoader.loadModule(geodeCommonDescriptor.getName())).isNotNull();
+    assertThat(moduleLoader.loadModule(geodeCommonsServiceDescriptor.getName())).isNotNull();
     assertThat(moduleLoader.loadModule(module1Descriptor.getName())).isNotNull();
     Module module = moduleLoader.loadModule(module2Descriptor.getName());
     assertThat(module).isNotNull();


[geode] 05/08: GEODE-8148 - Implement unloadModule. (#5151)

Posted by ud...@apache.org.
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 73c519a311ed6e49ac393e25e1615e486727e775
Author: Patrick Johnson <pj...@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