This is an automated email from the ASF dual-hosted git repository.
desruisseaux pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-compiler-plugin.git
The following commit(s) were added to refs/heads/master by this push:
new 203cb86 Add documentation for multi-release and multi-module projects
(#976)
203cb86 is described below
commit 203cb86eaea9c8809fe1d84e6d3d2ca15185fedb
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Tue Oct 14 22:37:08 2025 +0200
Add documentation for multi-release and multi-module projects (#976)
---
src/site/fml/faq.fml | 3 +-
src/site/markdown/examples/annotation-processor.md | 6 +
.../examples/compile-using-different-jdk.md | 6 +-
src/site/markdown/index.md | 9 +
src/site/markdown/module-info-patch.md | 144 ++++++++++++
src/site/markdown/modules.md | 180 +++++++++++++++
src/site/markdown/multirelease.md | 6 +-
src/site/markdown/sources.md | 244 +++++++++++++++++++++
src/site/site.xml | 7 +-
9 files changed, 596 insertions(+), 9 deletions(-)
diff --git a/src/site/fml/faq.fml b/src/site/fml/faq.fml
index ec0b1ca..b308a16 100644
--- a/src/site/fml/faq.fml
+++ b/src/site/fml/faq.fml
@@ -34,8 +34,7 @@ under the License.
in the build of your project for source generation (in that way the
sources are generated each time).
</p>
<p>For more information about Modello, please visit the
- <a href="https://codehaus-plexus.github.io/modello/">Modello
website</a>
- .
+ <a href="https://codehaus-plexus.github.io/modello/">Modello
website</a>.
</p>
</answer>
</faq>
diff --git a/src/site/markdown/examples/annotation-processor.md
b/src/site/markdown/examples/annotation-processor.md
index be703c5..e799d60 100644
--- a/src/site/markdown/examples/annotation-processor.md
+++ b/src/site/markdown/examples/annotation-processor.md
@@ -22,7 +22,9 @@ under the License.
[Annotation
processing](https://docs.oracle.com/en/java/javase/23/docs/specs/man/javac.html#annotation-processing)
is used to let the compiler generate source code based on annotations.
For example, the [Hibernate Processor](https://hibernate.org/orm/processor/)
provides an annotation processor to generate the JPA metamodel.
+
## Recommended way to activate annotation processing
+
Up to JDK 23, the compiler automatically scanned the classpath for annotation
processors and executed all found by default.
For security reasons, this got disabled by default since JDK 23 and annotation
processing needs to be activated explicitly.
The recommended way for this is to list all desired processors using either
the `<annotationProcessors>` plugin configuration
@@ -31,7 +33,9 @@ Only those processors will get executed by the compiler.
The following example shows how to activate the Hibernate Processor.
+
### Maven 3
+
When using Maven 3 and Maven Compiler Plugin version 3.x you do this using the
following configuration.
```xml
@@ -59,7 +63,9 @@ When using Maven 3 and Maven Compiler Plugin version 3.x you
do this using the f
</project>
```
+
### Maven 4
+
With Maven 4 and Maven Compiler Plugin 4.x the way described above got
deprecated and will be removed in a future version of the plugin.
Configuration now makes use of the new `processor` dependency type to shorten
the configuration,
give control over the placement on class-path or module-path, and make the
information available to other plugins.
diff --git a/src/site/markdown/examples/compile-using-different-jdk.md
b/src/site/markdown/examples/compile-using-different-jdk.md
index 1df2feb..8d536f0 100644
--- a/src/site/markdown/examples/compile-using-different-jdk.md
+++ b/src/site/markdown/examples/compile-using-different-jdk.md
@@ -79,9 +79,9 @@ or sets an environment variable, so that the build remains
portable.
[...]
<profile>
<id>compiler</id>
- <properties>
- <JAVA_11_HOME>/usr/lib/jvm/java-11-openjdkk</JAVA_11_HOME>
- </properties>
+ <properties>
+ <JAVA_11_HOME>/usr/lib/jvm/java-11-openjdkk</JAVA_11_HOME>
+ </properties>
</profile>
</profiles>
[...]
diff --git a/src/site/markdown/index.md b/src/site/markdown/index.md
index 54d10e1..5f4ff8b 100644
--- a/src/site/markdown/index.md
+++ b/src/site/markdown/index.md
@@ -52,6 +52,15 @@ Of course, patches are welcome, too.
Contributors can check out the project from our [source
repository](./scm.html) and will find supplementary information
in the [guide to helping with
Maven](http://maven.apache.org/guides/development/guide-helping.html).
+The following pages describes how to use the plugin beyond the default
+"one source directory, one module, one release" default configuration:
+
+* [Declaration of source directories](./sources.html)
+* [Multi-release project](./multirelease.html)
+* [Modular project](./modules.html)
+* [Module-info patch for tests](./module-info-patch.html)
+
+
# Examples
To provide you with better understanding on some usages of the Compiler Plugin,
diff --git a/src/site/markdown/module-info-patch.md
b/src/site/markdown/module-info-patch.md
new file mode 100644
index 0000000..1b32bf1
--- /dev/null
+++ b/src/site/markdown/module-info-patch.md
@@ -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.
+-->
+
+# Module-info patch
+
+For white box testing, it is necessary to use compiler options such as
+`--patch-module`, `--add-modules`, `--add-reads`, `--add-exports` and
`--add-opens`.
+Writing these options inside the Maven `<compilerArgs>` XML element is
tedious, redundant
+(the name of the module to patch is repeated in every occurrence of some
options), error prone,
+and must be repeated in every plugins that depends on the tests (Surefire,
Javadoc for test documentation, _etc._).
+An alternative is to put a `module-info.java` file in the tests which
*replace* the `module-info.java` file of the main code.
+However, it forces the developer to repeat all the content of the main
`module-info.java`
+into the test `module-info.java` before to add test-specific statements.
+This is tedious if the main `module-info.java` is large, and risky if the two
files become out of sync.
+
+Instead of defining a `module-info.java` file in test, Maven projects can
define a `module-info-patch.maven`.
+The content of `module-info-patch.maven` uses the same syntax as Java, C/C++,
JavaScript, Groovy, _etc._
+(comments between `/*` … `*/` or after `//`, blocks between `{` … `}`,
statements ending with `;`)
+but is not Java, hence the `.maven` file suffix.
+The general principles are:
+
+* Everything that a developer would like to change in a `module-info.java`
file for testing purposes is declared in `module-info-patch.maven`.
+* Everything that is not in `module-info.java` is not in
`module-info-patch.maven` neither.
+ In particular, everything that specify paths to JAR files or paths to source
code stay in the `pom.xml` file.
+* All keywords except `patch-module`, `SUBPROJECT-MODULES` and
`TEST-MODULE-PATH`
+ map directly to Java compiler or Java launcher options.
+
+Compared to declaring options in `<compilerArgs>` XML elements, the
`module-info-patch.maven` file is more readable,
+keep the options in separated files for each module on which the options are
applied, is less redundant as it avoids
+the need to repeat the module name in every `--add-reads`, `--add-exports` and
`--add-opens` options,
+and is more flexibly as it is translated in slightly different options for
compilation and test executions
+(e.g. `TEST-MODULE-PATH` means modules having `test` and `test-only` Maven's
scope at compilation time,
+but means modules having `test` and `test-runtime` Maven's scope at execution
time).
+
+
+## Syntax
+
+The syntax is:
+
+* The same styles of comment as Java (`/*` … `*/` and `//`) are accepted.
+* The first tokens, after comments, shall be `patch-module` followed by the
name of the module to patch.
+* All keywords inside `patch-module` are Java compiler or Java launcher
options without the leading `--` characters.
+* Each option value ends at the `;` character, which is mandatory.
+
+The accepted keywords are `add-modules`, `limit-modules`, `add-reads`,
`add-exports` and `add-opens`.
+Note that they are options where the values are package or module names, not
paths to source or binary files.
+Options with path values (`--module-path`, `--module-source-path`,
`--patch-module`, _etc._)
+continue to be derived from the dependencies declared in the POM.
+
+
+### Options applying to all modules
+
+All options declared in a `module-info-patch.maven` file apply only to the
module declared after the `patch-module` token,
+except the `--add-modules` and `--limit-modules` options.
+These two options apply to all modules in a multi-modules project,
+because these options given to `java` or `javac` expect no module name.
+Therefore, it is not necessary to repeat `add-modules TEST-MODULE-PATH` in all
modules:
+declaring that particular option in only one module of a multi-modules project
is sufficient.
+If the `--add-modules` or `--limit-modules` options are declared in many
`module-info-patch.maven` files of a multi-modules project,
+then the effective value is the union of the values declared in each file,
without duplicated values.
+
+
+### Special option values
+
+The following option values have special meanings:
+
+* `SUBPROJECT-MODULES`: all other modules in the current Maven (sub)project.
+ * This is Maven-specific, not a standard value recognized by Java tools.
+ * Allowed in: `add-exports`.
+* `TEST-MODULE-PATH`: all dependencies having a test scope in the build tools.
+ * This is specific to this format, not a standard value recognized by Java
tools.
+ * Allowed in: `add-modules`, `add-reads` and `add-exports` options.
+* `ALL-MODULE-PATH`: everything on the module path, regardless if test or main.
+ * This is a standard value accepted by the Java compiler.
+ * Allowed in: `add-modules` option.
+* `ALL-UNNAMED`: all non-modular dependencies.
+ * This is a standard value accepted by the Java compiler.
+ * Allowed in: `add-exports` option.
+
+
+## Example
+
+Below is an example of a `module-info-patch.maven` file content
+for modifying the `module-info` of a module named `org.foo.bar`:
+
+```java
+/*
+ * The same comments as in Java are allowed.
+ */
+patch-module org.foo.bar { // Put here the name of the module
to patch.
+ add-modules TEST-MODULE-PATH; // Recommended value in the majority
of cases.
+
+ add-reads org.junit.jupiter.api, // Frequently used dependency for
tests.
+ my.product.test.fixture; // Put here any other dependency
needed for tests.
+
+ add-exports org.foo.bar.internal // Name of a package which is
normally not exported.
+ to org.junit.jupiter.api, // Any module that need access to
above package for testing.
+ org.something.else; // Can export to many modules, as a
coma-separated list.
+
+ add-exports org.foo.bar.fixtures // Another package to export. It may
be a package defined in the tests.
+ to org.foo.bar.other; // Another module of this project
which may want to reuse test fixtures.
+}
+```
+
+
+### How module info patches are compiled
+
+`module-info-patch.maven` are compiled into a file of options in the following
ways:
+
+* `add-modules org.foo, org.bar;` is translated to `--add-modules
org.foo,org.bar`.
+ * Note: spaces between `org.foo` and `org.bar` are removed for interpreting
the option values as a single argument.
+* `limit-modules org.foo, org.bar;` is translated to `--limit-modules
org.foo,org.bar`.
+ * Note: idem regarding spaces removal.
+* `add-reads org.foo, org.bar;` is translated to `--add-reads
org.patched=org.foo,org.bar`
+ where `org.patched` is the module name declared in the first statement of
the `module-info-patch` file.
+* `add-exports com.biz to org.foo, org.bar;` is translated to `--add-exports
org.patched/com.biz=org.foo,org.bar`
+ where `org.patched` is as above.
+* `add-opens com.biz to org.foo, org.bar;` is translated to `--add-opens
org.patched/com.biz=org.foo,org.bar`
+ like above but only for runtime execution, not for compilation.
+
+There is a separated `module-info-patch.maven` file for each module,
+and the Maven compiler plugin merges them in a single set of options for
`java` and `javac`.
+While this format does not require the use of module source hierarchy, it fits
nicely in that hierarchy.
+
+The results of the translation to compiler options can be seen in the
`target/javac.args` and `target/javac-test.args` files.
+Those files are produced when the build failed or when Maven was executed with
the `--verbose` command-line option.
+In addition, a slightly different set of options, suitable for tests
execution, is written in the
+`target/test-classes/META-INF/maven/module-info-patch.args` file.
diff --git a/src/site/markdown/modules.md b/src/site/markdown/modules.md
new file mode 100644
index 0000000..b9b4724
--- /dev/null
+++ b/src/site/markdown/modules.md
@@ -0,0 +1,180 @@
+<!--
+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.
+-->
+
+# Modular projects
+
+The Maven 3 way to make a modular project is to put a `module-info.java` file
in the root directory of Java source files.
+Because the compilation and execution of tests usually require an amended
version of module information,
+Maven 3 allows to overwrite that file with another `module-info.java` file
placed in the test source directory.
+While this approach is still supported in Maven 4 for compatibility reasons,
+it is deprecated and may no longer be supported in a future version.
+Developers are encouraged to migrate to the approach described below.
+
+
+## Maven 3
+
+The directory layout of a modular project in Maven 3 was as below:
+
+```
+src
+├─ main
+│ └─ java
+│ ├─ module-info.java
+│ └─ org/foo/bar/*.java
+├─ test
+│ └─ java
+│ ├─ module-info.java (optional)
+│ └─ org/foo/bar/*.java
+└─ target
+ └─ classes
+ └─ org/foo/bar/*.class
+```
+
+An alternative to the `test/java/module-info.java` file is to declare compiler
arguments
+such as `--add-reads` in the `<testCompilerArgs>` element of the plugin
configuration.
+
+
+## Maven 4 with package hierarchy
+
+Maven 4 allows the same directory layout as Maven 3.
+However, the `module-info.java` file in the test directory *should* be
+replaced by a `module-info-patch.maven` file in the same directory.
+
+```
+src
+├─ main
+│ └─ java
+│ ├─ module-info.java
+│ └─ org/foo/bar/*.java
+├─ test
+│ └─ java
+│ ├─ module-info-patch.maven (optional)
+│ └─ org/foo/bar/*.java
+└─ target
+ └─ classes
+ └─ org/foo/bar/*.class
+```
+
+The Maven compiler automatically adds `--patch-module`, `--add-modules` and
`--add-reads` arguments for compiling the tests.
+If more `--add-reads` arguments are needed, or if `--add-modules`,
`--add-exports` or `--add-opens` arguments are also needed,
+then a `module-info-patch.maven` file (syntax described below) can be placed
in the `test/java` directory.
+This Maven file is preferred to a `module-info.java` file in the test
directory because the Maven file
+*completes* the main `module-info.class` (using compiler arguments) instead of
*replacing* it.
+
+
+### Limitation
+
+When using the package hierarchy, problems may occur if the module name is a
single name without `.` separator
+(for example, `foo` or `bar` but not `foo.bar`) and that name is identical to
a package name.
+In such case, the hack implemented in the Maven compiler plugin for Maven 3
compatibility
+become confused about whether a directory named `foo` represents the module or
the package.
+For avoiding ambiguity, use module names containing at least one `.` character
+(as it should be when using the reverse domain name convention)
+or use the module source hierarchy described below.
+
+
+## Maven 4 with module source hierarchy
+
+The [module source
hierarchy](https://docs.oracle.com/en/java/javase/17/docs/specs/man/javac.html#directory-hierarchies)
+introduces one additional directory level in the paths to source Java files
and to compiled classes.
+The name of this directory is the Java module name,
+and the directory is always present even in projects containing only one
module.
+More than one Java module can be present in the same Maven sub-project.
+Such multi-module projects have advantages such as resolving compiler warnings
+in forward references to dependent modules and easier sharing of test code
between modules.
+For example, a Maven project for a single Java module named `org.foo.bar`
would have the following directory layout:
+
+```
+src
+├─ org.foo.bar
+│ ├─ main
+│ │ └─ java
+│ │ ├─ module-info.java
+│ │ └─ org/foo/bar/*.java
+│ └─ test
+│ └─ java
+│ ├─ module-info-patch.maven (optional)
+│ └─ org/foo/bar/*.java
+└─ target
+ └─ classes
+ └─ org.foo.bar
+ └─ org/foo/bar/*.class
+```
+
+Note that the output directory also contains an `org.foo.bar` directory level.
+That directory level is generated by `javac`, this is not a convention
invented by Maven.
+
+Above layout can be declared with the following fragment in the `pom.xml` file.
+Since this example uses the default directory layout for modular projects,
+the `<directory>` elements do not need to be specified.
+
+```xml
+<build>
+ <sources>
+ <source>
+ <module>org.foo.bar</module>
+ </source>
+ <source>
+ <scope>test</scope>
+ <module>org.foo.bar</module>
+ </source>
+ </sources>
+</build>
+```
+
+## Black Box testing
+
+"Black Box testing" refers to tests executed without access to the internal
code of the project to test.
+Internal codes include package-private classes, interfaces, methods and
fields, and also all non-exported packages.
+Because the module source hierarchy allows any number of Java modules in the
same Maven sub-project,
+it is easy to add an `org.foo.bar.test` module which will test the
`org.foo.bar` module as if it was
+an ordinary client application.
+
+
+## White Box testing
+
+"White Box testing" refers to tests which have an access to the internal
classes of the project to test.
+For any `<source>` element with the `test` scope, all Java code placed in the
directory managed by that
+element is automatically white box testing for the module declared in the
`<module>` child element.
+Access to package-private types and members is granted by placing the code in
the same package as the code to test.
+Access to non-exported modules is implicit, but only for the module where the
tests belong.
+
+
+## Reusing test fixtures of another module
+
+The Maven 3 way (`test-jar`) is still supported in Maven 4.
+However, when using module source hierarchy, it is easier to place test
fixtures
+in the test code of any module which is required by all modules that need
these fixtures.
+The test fixtures can be in any package, not necessarily a package that exists
in the main code.
+Then, the `module-info-patch.maven` file can export that package to the other
modules.
+For example if the test fixtures are placed in the `org.foo.bar.test` package
of the `org.foo.bar` module:
+
+```java
+patch-module org.foo.bar { // Put here the name of the module to
patch.
+ add-modules TEST-MODULE-PATH; // Recommended value in the majority of
cases.
+ add-reads TEST-MODULE-PATH;
+
+ add-exports org.foo.bar.test // The package that contains the test
fixtures.
+ to SUBPROJECT-MODULES; // The other modules which want to use
those test fixtures.
+}
+```
+
+`SUBPROJECT-MODULES` is a Maven-specific keyword for exporting to all other
Java modules
+in the Maven (sub)project being compiled. It can be replaced by an explicit
list of modules.
+That's all, no need to deploy or install a test JAR.
diff --git a/src/site/markdown/multirelease.md
b/src/site/markdown/multirelease.md
index 29529d0..a91ad7a 100644
--- a/src/site/markdown/multirelease.md
+++ b/src/site/markdown/multirelease.md
@@ -22,7 +22,7 @@ under the License.
With [JEP-238](http://openjdk.java.net/jeps/238) the support of multirelease
JARs was introduced.
This means that you can have Java version dependent classes inside one JAR.
Based on the runtime, it will pick up the best matching version of a class.
-The files of a multi-release project are organized like below:
+The output files of a multi-release project are organized like below:
```
.
@@ -112,7 +112,7 @@ These directories are declared together with the Java
release like below:
<source>
<scope>test</scope>
<directory>src/test/java</directory>
- <targetVersion>17</targetVersion>
+ <targetVersion>21</targetVersion> <!-- Can often be omitted for
tests -->
</sources>
[...]
</build>
@@ -121,4 +121,4 @@ These directories are declared together with the Java
release like below:
The Maven Compiler plugin will take care of invoking `javac` once for each
target version in increasing version order,
with the `--release` option set to the given `<targetVersion>` value, and
with the classes of previous versions added to the class-path or module-path
with most recent versions having precedence.
-The compiled classes are written in the appropriate `target/classes` or
`target/classes/META-INF/versions` directory.
+The compiled classes are written in the `target/classes` and
`target/classes/META-INF/versions` directories.
diff --git a/src/site/markdown/sources.md b/src/site/markdown/sources.md
new file mode 100644
index 0000000..77a6972
--- /dev/null
+++ b/src/site/markdown/sources.md
@@ -0,0 +1,244 @@
+<!--
+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.
+-->
+
+# Declaration of source directories in Maven 4
+
+By default, Maven compiles all `*.java` files in the `src/main/java` directory
as the main Java code
+and all `*.java` files in the `src/test/java` directory as the test Java code.
+This is suitable for a project in a single Java module targeting a single Java
release.
+This page describes how to use different or additional directories in Maven 4.
+
+The Maven 3 `<sourceDirectory>` and `<testSourceDirectory>` elements are
deprecated
+and should be replaced by the new `<sources>` element introduced in Maven 4.
+This new element allows multi-source, multi-release and multi-module projects,
+as shown in sub-sections of this page.
+Instead of:
+
+```xml
+<project>
+ <build>
+ <sourceDirectory>my-custom-dir/foo</sourceDirectory>
+ <testSourceDirectory>my-custom-dir/bar</testSourceDirectory>
+ </build>
+</project>
+```
+
+One can write:
+
+```xml
+<project>
+ <build>
+ <sources>
+ <source>
+ <scope>main</scope> <!-- Can be omited as it is the default -->
+ <directory>my-custom-dir/foo</directory>
+ </source>
+ <source>
+ <scope>test</scope>
+ <directory>my-custom-dir/bar</directory>
+ </source>
+ </sources>
+ <build>
+</project>
+```
+
+Note that the declaration of a `<sources>` element *replaces* the default
values.
+If a `<source>` element is defined for one of the `main` or `test` scopes,
then a
+`<source>` element should generally be defined for the other scope
+even if the latter use the default directory.
+See the example in next sub-section.
+
+
+## Declaration of many source directories
+
+External plugins such as `build-helper-maven-plugin` are no longer needed
+and should be replaced by the build-in `<sources>` elements as shown below.
+Note that the directories of the first and last `<source>` elements are omitted
+as their default values are `src/main/java` and `src/test/java` respectively.
+
+```xml
+<project>
+ <build>
+ <sources>
+ <source>
+ <scope>main</scope>
+ <!-- Default directory is src/main/java -->
+ </source>
+ <source>
+ <scope>main</scope> <!-- Can be omited as it is the default -->
+ <directory>src/extension/java</directory>
+ </source>
+ <source>
+ <scope>test</scope>
+ <!-- Default directory is src/test/java -->
+ </source>
+ </sources>
+ <build>
+</project>
+```
+
+
+## Multi-releases project
+
+The new compiler plugin handles automatically multiple executions of `javac`
with different `--release` option values
+together with automatic adjustments of class-path, module-path and output
directories for producing a multi-releases project.
+Example:
+
+```xml
+<project>
+ <build>
+ <sources>
+ <source>
+ <targetVersion>17</targetVersion>
+ <!-- Default directory is src/main/java -->
+ </source>
+ <source>
+ <targetVersion>21</targetVersion>
+ <directory>src/main/java_21</directory>
+ </source>
+ <source>
+ <scope>test</scope>
+ <!-- Default directory is src/test/java -->
+ </source>
+ </sources>
+ </build>
+</project>
+```
+
+
+## Multi-module project
+
+Maven 4 supports the Java [module source
hierarchy](https://docs.oracle.com/en/java/javase/17/docs/specs/man/javac.html#directory-hierarchies)
+with the canvas that as of October 2025, not all plugins have been updated yet.
+Compared to multi Maven sub-project, using multi Java module in a single Maven
sub-project has advantages such as
+resolving compiler warnings in references to dependent modules (the converse
of references to dependencies),
+easier sharing of test code between modules in the Maven sub-project (no need
for `test-jar`),
+and easier aggregated Javadoc for modules in the Maven sub-project.
+See the [modular projects](./modules.html) page for more information.
+For example, a Maven sub-project containing two Java modules named
`org.foo.bar.module1` and `org.foo.bar.module2`
+can be declared with the following fragment in the `pom.xml` file:
+
+```xml
+<build>
+ <sources>
+ <source>
+ <module>org.foo.bar.module1</module>
+ <!-- Default directory is src/org.foo.bar.module1/main/java -->
+ </source>
+ <source>
+ <module>org.foo.bar.module2</module>
+ <!-- Default directory is src/org.foo.bar.module2/main/java -->
+ </source>
+ <source>
+ <scope>test</scope>
+ <module>org.foo.bar.module1</module>
+ <!-- Default directory is src/org.foo.bar.module1/test/java -->
+ </source>
+ <source>
+ <scope>test</scope>
+ <module>org.foo.bar.module2</module>
+ <!-- Default directory is src/org.foo.bar.module2/test/java -->
+ </source>
+ </sources>
+</build>
+```
+
+The default directory layout is then as below:
+
+```
+src
+├─ org.foo.bar.module1
+│ ├─ main
+│ │ ├─ java
+│ │ │ └─ org/foo/bar/**/*.java
+│ └─ test
+│ └─ java
+│ └─ org/foo/bar/**/*Test.java
+└─ org.foo.bar.module2
+ ├─ main
+ │ └─ java
+ │ └─ org/foo/bar/**/*.java
+ └─ test
+ └─ java
+ └─ org/foo/bar/**/*Test.java
+```
+
+
+### Current support
+
+As of October 2025, only the Maven Compiler Plugin supports module source
hierarchy.
+The following plugins need to be updated:
+
+* Maven Surefire plugin
+* Maven JAR plugin
+* Maven Javadoc plugin
+
+
+## Include/exclude filters
+
+The Maven 3 way to declare include/exclude filters is still supported,
+but should be replaced by the `<sources>` element when applicable.
+Those two ways are not strictly equivalent:
+
+* The Maven 4 way specifies filters independently for each source directory.
+ These filters will be applied by all plugins that migrated to the Maven 4
API, not only the compiler plugin.
+* Conversely, the Maven 3 way specifies filters which will be applied only by
the compiler plugin.
+ However, these filters apply to all source directories.
+
+The following (Maven 3) specifies a filter applied on all source directories
but only by the compiler plugin:
+
+```xml
+<project>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>**/Foo*.java</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
+```
+
+The following (Maven 4) specifies a filter applied only on the specified
directories,
+but potentially used (when relevant) by all plugins upgraded to Maven 4:
+
+```xml
+<project>
+ <build>
+ <sources>
+ <source>
+ <directory>src/main/java</directory>
+ <excludes>
+ <exclude>**/Foo*.java</exclude>
+ </excludes>
+ </source>
+ <source>
+ <scope>test</scope>
+ <directory>src/test/java</directory>
+ </source>
+ </sources>
+ </build>
+</project>
+```
diff --git a/src/site/site.xml b/src/site/site.xml
index b6b0548..f36a892 100644
--- a/src/site/site.xml
+++ b/src/site/site.xml
@@ -32,6 +32,12 @@ under the License.
<item name="License" href="https://www.apache.org/licenses/"/>
<item name="Download" href="download.html"/>
</menu>
+ <menu name="Configuration">
+ <item name="Multi-source project" href="sources.html"/>
+ <item name="Multi-release project" href="multirelease.html"/>
+ <item name="Multi-module projects" href="modules.html"/>
+ <item name="Module-info patch for tests" href="module-info-patch.html"/>
+ </menu>
<menu name="Examples">
<item name="Compile Using A Different JDK"
href="examples/compile-using-different-jdk.html"/>
<item name="Compile Using the --release javac Option"
href="examples/set-compiler-release.html"/>
@@ -39,7 +45,6 @@ under the License.
<item name="Pass Compiler Arguments"
href="examples/pass-compiler-arguments.html"/>
<item name="Non-javac compilerIds" href="non-javac-compilers.html"/>
<item name="Older projects with module-info"
href="examples/module-info.html"/>
- <item name="MultiRelease" href="multirelease.html"/>
<item name="Perform annotation processing"
href="examples/annotation-processor.html"/>
</menu>
</body>