gnodet commented on code in PR #976: URL: https://github.com/apache/maven-compiler-plugin/pull/976#discussion_r2429689233
########## src/site/markdown/module-info-patch.md: ########## @@ -0,0 +1,137 @@ +<!-- +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: Review Comment: I think best practices is to put an empty line after a header. ########## src/site/markdown/module-info-patch.md: ########## @@ -0,0 +1,137 @@ +<!-- +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 Review Comment: ```suggestion ### Special option values ``` ########## src/site/markdown/module-info-patch.md: ########## @@ -0,0 +1,137 @@ +<!-- +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 Review Comment: ```suggestion ### Options applying to all modules ``` ########## src/site/markdown/modules.md: ########## @@ -0,0 +1,178 @@ +<!-- +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 Review Comment: ```suggestion ### Limitation ``` ########## src/site/markdown/sources.md: ########## @@ -0,0 +1,242 @@ +<!-- +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 Review Comment: ```suggestion ### Current support ``` ########## src/site/markdown/module-info-patch.md: ########## @@ -0,0 +1,137 @@ +<!-- +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 Review Comment: ```suggestion ## Example ``` ########## src/site/markdown/module-info-patch.md: ########## @@ -0,0 +1,137 @@ +<!-- +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 Review Comment: ```suggestion ## Syntax ``` ########## src/site/markdown/module-info-patch.md: ########## @@ -0,0 +1,137 @@ +<!-- +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 Review Comment: ```suggestion ### How module info patches are compiled ``` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
