diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index a945f20..b54acf6 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -27,8 +27,12 @@ All notable changes to this documentation project will be documented in this fil * Initial repository structure * README with project overview -* Documentation build pipeline (Maven + AsciiDoctor) +* Documentation build pipeline (Apache Maven + AsciiDoctor) * GitHub Actions workflow for CI/CD * Netlify deployment for PR previews * GitHub Pages deployment for main branch -* `docs/index.adoc` with documentation outline \ No newline at end of file +* `docs/index.adoc` with documentation outline + +''' + +_Apache Maven is a trademark of the https://www.apache.org/[Apache Software Foundation]._ \ No newline at end of file diff --git a/README.adoc b/README.adoc index 44a70e0..12534e5 100644 --- a/README.adoc +++ b/README.adoc @@ -16,7 +16,7 @@ KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. //// -= Maven Modular Sources Documentation += Apache Maven Modular Sources Documentation :icons: font :toc: left :toclevels: 2 @@ -70,4 +70,8 @@ Generated documentation will be in `target/generated-docs/`. == License -Documentation is provided under the Apache License 2.0. \ No newline at end of file +Documentation is provided under the Apache License 2.0. + +''' + +_Apache Maven is a trademark of the https://www.apache.org/[Apache Software Foundation]._ \ No newline at end of file diff --git a/docs/index.adoc b/docs/index.adoc index 4f3a0fe..8c2d87f 100644 --- a/docs/index.adoc +++ b/docs/index.adoc @@ -16,7 +16,7 @@ KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. //// -= Java Modules in Maven: Documentation += Java Modules in Apache Maven: Documentation :icons: font :toc: left :toclevels: 2 @@ -91,7 +91,7 @@ This documentation covers the following topics: [[table:topics:introduction]] 2+| *Introduction to Maven and Java Modules* -| Vision (TBD) +| xref:vision.adoc[Vision] | Shift from Maven modules to Java Modules as primary compilation units | Architecture (TBD) @@ -134,4 +134,8 @@ To add new documentation: . Create an AsciiDoc file in this directory . Add an entry to the table in the Topics section -. Submit a pull request for review \ No newline at end of file +. Submit a pull request for review + +''' + +_Apache Maven is a trademark of the https://www.apache.org/[Apache Software Foundation]._ \ No newline at end of file diff --git a/docs/vision.adoc b/docs/vision.adoc new file mode 100644 index 0000000..9443c0c --- /dev/null +++ b/docs/vision.adoc @@ -0,0 +1,241 @@ +//// +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. +//// += Vision: Java Modules and Apache Maven (4) +:icons: font +:toc: left +:toclevels: 2 + +ifdef::env-github[] +:tip-caption: :bulb: +:note-caption: :information_source: +:important-caption: :heavy_exclamation_mark: +:caution-caption: :fire: +:warning-caption: :warning: +endif::[] + +[sidebar] +.TL;DR +**** +Java Modules enable strong encapsulation and explicit dependencies at the language level. +Their source code can be organized in a single source tree, separated by module names. +This allows Maven to compile multiple Java Modules in one project into multiple modular JAR files efficiently. +Maven resolves external dependencies and assembles the module-path, enabling the compiler and JVM to enforce proper module boundaries. + +Using this opportunity to provide modularization on the language level imposes a significant shift in how Maven works with modules. +In particular, the *1:1 relationship of Maven module to major artifact (JAR) is no longer valid*. + +Each Maven project may result in multiple artifacts (JARs), each representing a Java Module in the future. +Consequently, many existing Maven concepts and mechanisms need to be revisited to align with this new reality. +**** + +== How Java Modules work + +Java Modules (aka _Java Platform Module System_ or _Project Jigsaw_, introduced in Java 9) provide compile-time and runtime encapsulation through `module-info.java` descriptors. + +Key characteristics: + +Explicit dependencies:: +`requires`-declarations explicitly state which modules a module depends on. +The module system ensures required modules are present and permits access between modules. + +Strong encapsulation:: +Only `exports`-declared packages are accessible to other modules. + +Compile-time and runtime verification:: +Both the compiler and the JVM enforce module boundaries. +The compiler catches access violations where possible, and the runtime system enforces encapsulation even for reflective access (thus improving security). + +Multi-module compilation:: +The Java compiler can compile an entire module graph from a structured source tree and handles full and incremental compilation efficiently across module boundaries. + +== Lifecycle Phases and Module Enforcement + +Understanding when Maven is in control versus when the JVM takes over is fundamental to understanding the challenges of Java Module support. + +=== Three Distinct Phases + +Compile time:: +Maven orchestrates the build environment by resolving dependencies and setting up the module source path and module path for the compiler. +The Java compiler (`javac`) enforces module boundaries during compilation, checking `requires` declarations and `exports` visibility. +Maven translates its dependency model (coordinates, scopes) into the module path of dependency JARs that `javac` expects. + +Test time:: +Maven continues to orchestrate, but testing introduces additional complexity. +Whitebox testing (accessing internal packages) requires `--patch-module` to merge test code into the module under test. +The compiler and JVM both participate in enforcement during this phase. +Maven must set up the test environment to satisfy both compilation requirements and runtime test execution. + +Runtime:: +*Maven is no longer involved.* +The JVM's module system takes full control, enforcing boundaries based solely on the `module-info.class` files embedded in JARs. +No `pom.xml` is consulted; no Maven coordinates exist at this level. +The application runs (or fails) based purely on Java Module semantics. + +[CAUTION] +==== +This simplified model covers the typical case where Maven builds and packages artifacts that later run independently. +Special cases exist where Maven controls runtime execution, (e.g., via the Maven Exec Plugin, mixed module-path and classpath execution, or integration tests). +We do not address these scenarios here. +==== + +=== The Responsibility Boundary + +[cols="1,1,1,2",options="header"] +|=== +| Phase | Orchestrator | Enforcer | What Drives Configuration + +| Compile +| Maven +| `javac` +| `pom.xml` dependencies + Project's Java Modules → module path + +| Test +| Maven +| `javac` + JVM +| `pom.xml` + test-specific flags (`--patch-module`) + +| Runtime +| JVM only +| JVM +| `module-info.class` in packaged JARs +|=== + +The critical insight: *Maven's responsibility ends at packaging.* +Once Maven has produced and deployed JARs, they must be self-sufficient. +The `module-info.class` in each JAR must accurately declare what the JVM will need to run the application. + +=== Why This Distinction Matters + +This phase separation is the root cause of several challenges in Maven's Java Module support: + +* *Metadata must bridge two worlds*: Maven produces artifacts at build time, but those artifacts must satisfy JVM requirements at runtime — without Maven present. + +* *Semantic translation is imperfect*: Java Module concepts (`requires static`, `requires transitive`) express runtime behavior, while Maven concepts (`optional`, scopes) express build-time relationships. These don't map 1:1. + +* *Build tool independence*: Consumers may use Gradle, Bazel, or manual compilation. +The `module-info.class` is the universal contract — it must be correct regardless of how a particular build system created it. + +The <> section outlines specific areas where these challenges manifest and require documentation. + +== How Maven worked with Modules in the past + +Maven 3's module concept predates Java Modules and serves a different purpose: + +Maven modules:: +Organizational units in a reactor build, each with its own `pom.xml`. + +One module = one artifact:: +Each Maven module produces exactly one primary artifact (JAR, WAR, etc.). + +Classpath-based by design:: +Maven 3 was built around the flat classpath model; no encapsulation enforcement at the JVM level. + +When Java Modules arrived, Maven 3 adapted minimally: + +* The compiler plugin (and others) gained module-path support +* Each Java Module still requires its own Maven module +* No native support for multi-module compilation +* Automatic detection of whether to place a dependency on classpath or module-path, with limited control when detection was wrong +* No easy way to set up `--patch-module` for whitebox testing; a common workaround was to overwrite `module-info.java` in the test directory, which has drawbacks + +This 1:1 mapping works but limits the benefits of the new multi-module compilation model. + +== How Maven (4) envisions Modules + +=== Module Source Hierarchy + +Maven 4 embraces the *Module Source Hierarchy* pattern (-> _modular sources_), allowing a single Maven project to compile multiple Java Modules: + +[source,text] +---- +project/ +├── pom.xml +└── src/ + ├── moda/ + │ └── main/java/ + │ ├── module-info.java + │ └── pkga/Main.java + └── modb/ + └── main/java/ + ├── module-info.java + └── pkgb/B.java +---- + +The Maven compiler plugin maps this layout directly to respective calls to `javac`, enabling: + +Single compilation:: +The Java compiler handles all modules together with proper (Java Module) dependency checking. + +Overlapping dependency concepts:: +- Java Module dependencies drive compilation, including project-internal module resolution as well as runtime behavior. +- Maven coordinates enable artifact resolution (project-external modules) and publication (see below). + +Flexible artifact mapping:: +One Maven project can produce multiple module JARs (in the future). + +The POM declares sources explicitly: + +[source,xml] +---- + + + moda + modb + + +---- + +Maven subprojects (formerly known and declared as "modules") become optional organizational boundaries, not mandatory per-Java-Module requirements. + +=== Two Levels of Dependency Resolution + +With modular sources, dependency resolution operates at two distinct levels: + +Java Module resolution:: +The compiler and JVM resolve dependencies among modules by name. +Within the project's modular sources, the compiler handles this automatically. +At runtime, the JVM verifies that all required modules are present and accessible. + +Maven artifact resolution:: +Maven must still resolve external dependencies (libraries outside the project's modular sources) using Group, Artifact, and Version coordinates. +Maven locates these artifacts and makes them available to the compiler and (test) runtime as modules. +The `module-info.java` declares its requirements by module name; Maven's `pom.xml` maps those names to resolvable artifacts. + +== Implications + +The shift to modular sources requires documenting several areas in detail. +The following topics are covered (or planned) as separate documents: + +Consumer POM Generation (TBD):: +How Maven 4 generates consumer POMs that accurately reflect Java Module dependencies for downstream consumers. + +Dependency Scope Mapping (TBD):: +Analysis of how Java Module modifiers (`requires static`, `requires transitive`) map to Maven scopes — and where they don't. + +Testing Patterns (TBD):: +How whitebox testing works with `--patch-module` and how Maven 4's compiler plugin handles test sources automatically. + +Artifact Naming (TBD):: +How Java module names map to Maven artifact coordinates when one project produces multiple JARs. + +See the xref:index.adoc#section:topics[Topics] overview for the full list of documentation areas. + +''' + +_Apache Maven is a trademark of the https://www.apache.org/[Apache Software Foundation]._ \ No newline at end of file