You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 4 Next »

To be Reviewed By: August 17th 2020

Authors: Patrick Johnson

Status: Draft | Discussion | Active | Dropped | Superseded

Superseded by: N/A

Related: ClassLoader Isolation

Problem

Geode is comprised of multiple sub-projects, many of which depend on other sub-projects at runtime to work correctly; these dependencies are defined in each project's build.gradle file. Normally, this is not a problem because all of Geode's projects are present on the Java classpath at runtime, allowing sub-projects to access classes from other sub-projects as required. However, the changes proposed by the ClassLoader Isolation RFC will result in all sub-projects being loaded as separate modules with different ClassLoaders and no longer being on the system classpath, as they were before.

Once these modularizing changes go into effect, modules will no longer be able to access classes from other modules unless they explicitly create a dependency on them. In order to create dependencies between related modules, we need a way to determine at runtime which modules depended on which other modules, which, currently, we do not have.  In addition to creating dependencies between modules, we may also need to load modules that are not already loaded, when loading a module that depends on them. For example, imagine the scenario where module A depends on modules B and C which both have dependencies of their own represented by the below graphic.

dependency-hierarchy

Loading module A would require all of the modules in its dependency hierarchy (shown above) to be loaded. If the modules required by module A are not already loaded, they would have to be loaded for module A to function correctly. Without knowledge of this hierarchy at runtime, we would be unable to ensure that all the modules required by module A are loaded when it is.


Anti-Goals

This proposal is intended only to solve the above problem of determining at runtime which sub-projects/modules depend on which other sub-projects/modules and is not concerned with...

  • The implementation of modules in Geode
  • Refactoring Geode's sub-projects to break or change any existing dependencies between them
  • Adding or removing sub-projects

Solution

 The proposed solution is to add a manifest file with a "Dependent-Modules" attribute (or add the "Dependent-Modules" attribute to an existing manifest file) to the jar files of all Geode sub-projects. The "Dependent-Modules" attribute will consist of a space-delimited list of sub-projects required at runtime by the current sub-project, in the form {name}-{version}, for example:


"Dependent-Modules: geode-membership-1.14.0-build.0 geode-http-service-1.14.0-build.0 geode-management-1.14.0-build.0 geode-unsafe-1.14.0-build.0"


This list can be populated by a Gradle task at build time using the dependency information from each sub-project's build.gradle file. The "Dependent-Modules" attribute can then be read at runtime when loading the sub-project as a module and used to create the necessary dependencies on other modules.

The sample hierarchy shown in the graphic above is much cleaner than many of the actual relationships between Geode sub-projects. Below shows a more realistic hierarchy structure.

messy-hierarchy

Notice that the above hierarchy is not a tree, but a graph and that there are multiple paths between some modules, for example, A could get to C directly, or by going through D. While this may accurately represent the current dependencies between projects as they are defined in Gradle, it is unnecessarily complex given that modules can find each other via other modules; there only needs to be a single path between a module and the other modules it depends on.  The above hierarchy can be simplified by removing from the dependencies list of each sub-project, dependencies that are reachable via any other dependencies. By doing this, the above hierarchy can be simplified to something more like the diagram below.

clean-hierarchy

This simplified hierarchy has significantly fewer paths, but still satisfies all of the module's dependencies.


Changes and Additions to Public Interfaces

No anticipated changes to public interfaces.

Performance Impact

No anticipated performance impact.

Backwards Compatibility and Upgrade Path

No backward compatibility impact.

Prior Art

An alternative to this proposal would be to load every sub-project as a module at startup and create dependencies between every module and every other module. While this may solve the problem, it would also largely defeat the purpose of modularizing Geode in the first place.

FAQ

Answers to questions you’ve commonly been asked after requesting comments for this proposal.

Errata

What are minor adjustments that had to be made to the proposal since it was approved?


  • No labels