Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

Last active August 16, 2019 12:02
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nipafx/78fff173ae57404af3cf4cb6512f1ab8 to your computer and use it in GitHub Desktop.
Save nipafx/78fff173ae57404af3cf4cb6512f1ab8 to your computer and use it in GitHub Desktop.
JPMS Maturity Model

Maturity Model

Libraries, frameworks, and tools (IDEs, build tools) have widely varying support for the JPMS. I would like to create a model that makes it easy to judge a project for what it can and can't (yet) do - both for users and maintainers.

Conditions can usually be split into those for libraries/frameworks and those for tools, but that's not clear cut. Bytecode analysis tools, for example, may fall into both categories. So always look at both categories, and check which conditions apply to a given project.

This is work in progress - feedback welcome!

Level 0 - Denial: Don't break!

Libraries, frameworks

  • don't break on Java 9+ class path


  • don't break when declaration or descriptor is present
  • using only class path is ok

Level 1 - Guilt: Absolute minimum support

Libraries, frameworks

  • work on module path
  • define module name in manifest


  • syntax support for declaration
  • compile/run/test/package modules (i.e. use module path) when declaration/descriptor is present
  • place all dependencies on the module path
  • tests are patched into main modules

Level 2 - Bargaining: Refined and configurable support


  • ship modular JAR
  • keep working on class path
  • use lookup-based metaprogramming instead of reflection


Make dependency resolution strategies configurable and add more advanced ones:

  • all class path (as per level 0)
  • all module path (as per level 1)
  • only root and direct dependencies on module path, rest on class path
  • pull in service providers

For test frameworks, make test execution configurable and add more advanced options:

  • run tests on class path (as per level 0)
  • patch tests code into main module (i.e. main and test code run in the main module; as per level 1)
  • allow module declaration in test sources that is merged with main declaration and patch main code into test module (i.e. main and test code run in the test module)
  • allow module declaration in test sources that depends on main module (i.e. main and test code in separate modules)

Some examples

  • Maven compiler 3.8: 2 except configuration
  • Surefire 3.0.0-M2: 2
  • IntelliJ 2017.2
    • project builder: 1
    • test runner: 0
  • Eclipse Oxygen.1a: 1
Copy link

I would make a clear separation between at least libraries and applications. Every time I dive into these discussions it becomes clear that these 2 have different requirements. And there's probably a third category: support (like build tools and IDEs): these might not use the modulepath but do understand it.
When about Maven, it can be any of the three depending on how you use it.
As application it is not using the modulepath, and due to the age of Maven it is unlikely that it will ever run on the modulepath.
As library (when writing your own plugins or extensions) you'll face split package issues.
As support it is actually the plugins that are responsible and most of the plugins that should understand the modulepath do so.
What would be the conclusion and why? :)

Copy link

nipafx commented Jul 5, 2019

Thanks for you input Robert! :)

On your separation:

  • I don't think it's particularly important whether an IDE or build tool uses the module path for itself or not, so won't include that (for now). I should clarify that.
  • Seeing Maven as a framework to write plugins for, is an angle that I missed so far. I will include that.
  • I am aware that Maven's plugins need to be evaluated separately (see compiler and Surefire above).

The goal is to get all tools to share a lot of the same modes. At the moment, we can't start creating modules because Maven, IntelliJ, and Eclipse behave differently at compile and test time. This blocks us from adopting modules. Having a shared understanding of what's possible and how the possibilities rank, should give us a way to improve and unify tool support for the JPMS.

Copy link

karianna commented Jul 5, 2019

You should probably tie this into the java9plus adoption project over on AdoptOpenJDK.

Drop into the slack at and we can join forces

Copy link

Here's an issue for IDEA ... after that is fixed, it would support (also) to execute tests on the module path.

Copy link

One useful addition could be guidelines on how to reach the individual levels, e.g. for level 0 adjustments may be needed to libraries relying on JAXB (need to bring their own dependency in 11) and things like that.

Copy link

nipafx commented Aug 5, 2019

@gunnar: I think that would blow up the post and make it too unwieldy. I'll link to other sources describing that, though.

Copy link

This got a bit lost in twitter correspondence. But there is something missing about support for ModularLayers.
I believe a mature library should support modules that are loaded via ModulLayers.

This is non-trivial to get right, if you rely on cached lookup objects from each module. As you cannot keep strong references to them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment