Search code examples
javamavenmulti-modulejava-module

Difference between multi-module (pom) and java module system


I'm trying to understand the difference(s) between structuring a project with the Java Platform Module System (JPMS) versus structuring a project using multi-poms.

Is the main difference that the JPMS encapsulates the code while a multi-pom project separates project dependencies?

I've searched on google but I haven't found a good explanation on the differences, but rather I see the word module getting used interchangably.


Solution

  • The computing industry often recycles terms. Context is everything.

    The two kinds of “module” you present are unrelated, orthogonal issues.

    • The Java Platform Module System (JPMS) is a way to identify to the Java compiler namespaces amongst all the classes and methods available at runtime.
    • Multi-module in Apache Maven is a way to conjoin into one project what could be handled as separate projects. Each module in the project has its own POM with its own dependency and build settings, yet all can be managed as one super-project when combined as a Maven multi-module. Each module results in producing an artifact, such as a JAR or WAR file.

    Very simple apps in Java may use neither.

    • Ideally new Java apps would use the JPMS, but it is still technically optional. In a perfect world, JPMS would have been included in the original Java, but was in fact added only recently, in Java 9. JPMS is quite handy if your app will run as a standalone, with a JVM bundled, because you can include a JVM that has been stripped down to only the parts actually used by your particular app (see jlink, jpackage, and related tools enabled by JPMS).
    • Maven multi-module projects are generally only used for complicated projects such as an app that includes a piece of functionality which may be spun-off for use in other projects. Or a multi-module Maven project may be good for an app that combines both a frontend user-interface module along with a backend business-logic module where we want to manage each part separately yet combine them into a single deliverable, such as a Vaadin Flow web app.

    I can see how you could become confused, as both have to do with arranging classes. To oversimplify, Maven modules are about compile-time (dependency management and build automation) while Java Platform Module System is about runtime.


    I’ve read that Gradle is more adept at managing a multi-module project. You might consider switching from Maven to Gradle for your multi-module projects. Gradle obtains your dependencies from Maven repositories.


    You asked in a Comment:

    if you had to split up a monolith legacy app that is really several apps rolled into one, would you take a mutli-modual approach or JPMS approach?

    Again, project-modules and JPMS are orthogonal issues.

    You could modularize with JPMS either before or after splitting your legacy app project into separate app projects.

    Regarding project structure:

    • If you want to deliver each chunk of your legacy app as literally separate apps, then no need for a multi-module project; make them actual separate projects.
    • If you want to manage separately the dependencies and the build automation for each big chunk of your legacy app while still delivering a single artifact (app) at the end, then use a Maven multi-module project (or a Gradle multi-module project).