From 15bb8e5b2846902be28352a85b1380bb35ddee4e Mon Sep 17 00:00:00 2001 From: Martin Desruisseaux Date: Tue, 1 Jul 2025 10:03:52 +0200 Subject: [PATCH 01/11] Give more reasons for the Maven 4 way to declare an annotation processor. Avoid the use of a property that may not be defined on the user's machine. --- src/site/markdown/examples/annotation-processor.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/site/markdown/examples/annotation-processor.md b/src/site/markdown/examples/annotation-processor.md index efce889cf..be703c55b 100644 --- a/src/site/markdown/examples/annotation-processor.md +++ b/src/site/markdown/examples/annotation-processor.md @@ -61,7 +61,8 @@ When using Maven 3 and Maven Compiler Plugin version 3.x you do this using the f ### 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. +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. The following example shows this. ```xml @@ -107,7 +108,7 @@ You set the value of the `` configuration like every other [configuration] org.apache.maven.plugins maven-compiler-plugin - ${version.maven-compiler-plugin} + ... full From dcf4de1636a57738d8d03a9b972dc91e76223b1b Mon Sep 17 00:00:00 2001 From: Martin Desruisseaux Date: Sun, 29 Jun 2025 15:14:41 +0200 Subject: [PATCH 02/11] Convert the page about non-javac compiler from APT to Markdown format with no change in the text. We can use the format (APT versus Markdown) as a way to identify which files have been updated from Maven 3 to Maven 4. --- src/site/apt/non-javac-compilers.apt.vm | 77 ------------- .../markdown/examples/non-javac-compilers.md | 102 ++++++++++++++++++ 2 files changed, 102 insertions(+), 77 deletions(-) delete mode 100644 src/site/apt/non-javac-compilers.apt.vm create mode 100644 src/site/markdown/examples/non-javac-compilers.md diff --git a/src/site/apt/non-javac-compilers.apt.vm b/src/site/apt/non-javac-compilers.apt.vm deleted file mode 100644 index 6ca0aeeb7..000000000 --- a/src/site/apt/non-javac-compilers.apt.vm +++ /dev/null @@ -1,77 +0,0 @@ - ------ - Using Non-Javac Compilers - ------ - Edwin Punzalan - ------ - 2006-07-19 - ------ - -~~ 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. - -~~ NOTE: For help with the syntax of this file, see: -~~ http://maven.apache.org/doxia/references/apt-format.html - - -Using Non-Javac Compilers - - Contrary to this plugin's name, the Compiler Plugin does not compile the - sources of your project by itself. To compile, the Compiler Plugin uses - another class to compile them. - - The parameter <<>> determines which class will be used. - - By default, the Maven Compiler Plugin uses the <<>> compiler - bundled in the <<>> package of the standard Java library. - But it is possible to use any other compiler, as long the - implementation declares itself as a <<>> service. - To use such an implementation: - - * Add the compiler implementation in the Maven compiler plugin dependencies. - - * Declare the compiler's identifier in the <<>> element of the Maven plugin configuration. - The identifier value shall be the value returned by the <<>> method of the implementation. - - [] - - The example below shows how to use the Eclipse compiler <<>>. - Note: this configuration requires Maven 4 with Maven Compiler Plugin 4. - -+----- - - [...] - - [...] - - [...] - - maven-compiler-plugin - ${project.version} - - ecj - - - - org.eclipse.jdt - ecj - ${eclipseCompilerVersion} - - - - [...] - -+----- diff --git a/src/site/markdown/examples/non-javac-compilers.md b/src/site/markdown/examples/non-javac-compilers.md new file mode 100644 index 000000000..d4465fef6 --- /dev/null +++ b/src/site/markdown/examples/non-javac-compilers.md @@ -0,0 +1,102 @@ + + +# Using Non-Javac Compilers + +Contrary to this plugin's name, the Compiler Plugin does not compile the +sources of your project by itself. To compile, the Compiler Plugin uses +another class to compile them. + +The parameter `compilerId` determines which class will be used. + +By default, the version 4 of Maven Compiler Plugin uses the `javac` compiler +bundled in the `javax.tools` package of the standard Java library. +But it is possible to use any other compiler, as long the +implementation declares itself as a `javax.tools.JavaCompiler` service. +To use such an implementation: + +* Add the compiler implementation in the Maven compiler plugin dependencies. +* Declare the compiler's identifier in the `compilerId` element of the Maven plugin configuration. + The identifier value shall be the value returned by the `JavaCompiler.name()` method of the implementation. + +The example below shows how to use the Eclipse compiler `ecj`. +Note: This configuration requires Maven 4 with Maven Compiler Plugin 4. + +```xml + + [...] + + [...] + + [...] + + maven-compiler-plugin + ... + + ecj + + + + org.eclipse.jdt + ecj + ... + + + + + + +``` + + +## Maven 3 + +Version 3 of the Maven Compiler Plugin does not use the compiler directly. +Instead, it uses an intermediate layer called the Plexus Compiler. +The [Plexus Compiler](https://codehaus-plexus.github.io/plexus-compiler/) component +has some compiler identifiers available under the group `org.codehaus.plexus`. +To use any of the non-javac compilers with version 3.x of the Maven Compiler plugin, +you need to declare a dependency to the Plexus artifact in your project's `pom.xml`. +The example below shows how to use the `csharp` compiler: + +```xml + + [...] + + [...] + + [...] + + maven-compiler-plugin + ... + + csharp + + + + org.codehaus.plexus + plexus-compiler-csharp + ... + + + + + + +``` From e5f954e7997baf54b489600d5115493126401c84 Mon Sep 17 00:00:00 2001 From: Martin Desruisseaux Date: Sun, 29 Jun 2025 16:01:32 +0200 Subject: [PATCH 03/11] Remove mention of the `META-INF/jpms.args` file, which is not generated anymore. The new page is incomplete as it does not yet mention the replacement (`target/javac-test.args` is not really the replacement). This is because the code generating the replacement has not yet been merged. It is pending argreement to reach on mailing list. --- src/site/apt/examples/jpms_args.apt.vm | 62 --------------------- src/site/fml/faq.fml | 6 -- src/site/markdown/examples/jpms_args.apt.md | 49 ++++++++++++++++ 3 files changed, 49 insertions(+), 68 deletions(-) delete mode 100644 src/site/apt/examples/jpms_args.apt.vm create mode 100644 src/site/markdown/examples/jpms_args.apt.md diff --git a/src/site/apt/examples/jpms_args.apt.vm b/src/site/apt/examples/jpms_args.apt.vm deleted file mode 100644 index 723abae00..000000000 --- a/src/site/apt/examples/jpms_args.apt.vm +++ /dev/null @@ -1,62 +0,0 @@ - ------ - jpms.args - ------ - Robert Scholte - ------ - 2017-08-22 - ------ - -~~ 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. - -~~ NOTE: For help with the syntax of this file, see: -~~ http://maven.apache.org/doxia/references/apt-format.html - -JPMS.ARGS - - Java 9 comes with a new set of arguments related to the Java Platform Modular System. Besides the module path are - other new arguments which can change the behavior of the application. These can be used during both compile time - and runtime. This information is not stored in any class, but it can be interesting to know at runtime which extra - arguments were used at compile time. - - If any of these arguments is used, the <<>> is created. - Every argument gets its own line. - The following arguments will end up in this file: - - * <<<--upgrade-module-path>>> - - * <<<--add-exports>>> - - * <<<--add-reads>>> - - * <<<--add-modules>>> - - * <<<--limit-modules>>> - - * <<<--patch-module>>> - - [] - - The <<<--patch-module>>> values are different compared to the original values passed to the compiler. According to - the specification it looks like <<<--patch-module \=\(\\)\*>>> - However, files are system specific. For that reason the module names are used. If the jar itself contains the - patchcode, then an <<<_>>> (underscore) is used. As separators a <<<, >>> (comma + space) is used. - -+--- - --patch-module - =(, )* -+--- \ No newline at end of file diff --git a/src/site/fml/faq.fml b/src/site/fml/faq.fml index 7008fb4b4..ec0b1ca26 100644 --- a/src/site/fml/faq.fml +++ b/src/site/fml/faq.fml @@ -39,11 +39,5 @@ under the License.

- - Why is there sometimes a META-INF/jpms.args created? - -

Read jpms.args for all the details.

-
-
diff --git a/src/site/markdown/examples/jpms_args.apt.md b/src/site/markdown/examples/jpms_args.apt.md new file mode 100644 index 000000000..f3a99853d --- /dev/null +++ b/src/site/markdown/examples/jpms_args.apt.md @@ -0,0 +1,49 @@ + + +# Arguments related to Java Platform Module System + +Java 9 comes with a new set of arguments related to the Java Platform Modular System (JPMS). +Besides the module path there are other new arguments which can change the behavior of the application. +These can be used during both compile time and runtime. +Except the module path, these extra arguments should not be needed for compilation and execution of the main code +(if they are needed, then maybe the `module-info.java` file is incomplete). +But they may be needed for compilation and execution of tests. +In such case, at runtime it is useful to know which extra arguments were used at compile time. + + +## Debugging information + +If the compilation fails, version 4 of the Maven Compiler Plugin generates one of the following files, +depending on which scope (main or test) cannot be compiled: +These files are usually not generated when the build is successful, +but their generation can be forced by providing the `--verbose` option to the `mvn` command. + +* Main: `target/javac.args` +* Test: `target/javac-test.args` + +The following arguments are of particular interest, because they may be required at runtime. +These arguments should appear in the `javac-test.args` file only, not in `javac.args`. + + * `--upgrade-module-path` + * `--add-exports` + * `--add-reads` + * `--add-modules` + * `--limit-modules` + * `--patch-module` From 960d5f72dae006628432deaf833a84ff04616681 Mon Sep 17 00:00:00 2001 From: Martin Desruisseaux Date: Mon, 30 Jun 2025 14:22:23 +0200 Subject: [PATCH 04/11] Port the `module-info` page to markdown format together with the following changes: - Make more visible that users compiling for Java 9+ have nothing special to do. - Remove the text about how to use toolchain for compiling with Java 9+. It was obsolete since Maven 4 requires Java 17. - Adapt the text about how to use toolchain for compiling with a old JDK. --- src/site/apt/examples/module-info.apt.vm | 164 ---------------------- src/site/markdown/examples/module-info.md | 97 +++++++++++++ 2 files changed, 97 insertions(+), 164 deletions(-) delete mode 100644 src/site/apt/examples/module-info.apt.vm create mode 100644 src/site/markdown/examples/module-info.md diff --git a/src/site/apt/examples/module-info.apt.vm b/src/site/apt/examples/module-info.apt.vm deleted file mode 100644 index 09c5f69ca..000000000 --- a/src/site/apt/examples/module-info.apt.vm +++ /dev/null @@ -1,164 +0,0 @@ - ------ - Older projects with module-info - ------ - Robert Scholte - ------ - 2016-09-27 - ------ - -~~ 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. - -~~ NOTE: For help with the syntax of this file, see: -~~ http://maven.apache.org/doxia/references/apt-format.html - -Older projects with module-info - - Projects that want to be compatible with older versions of Java (i.e 1.8 or below bytecode and API), but also want to provide a - <<>> for use on Java 9+ runtime, must be aware that they need to call <<>> twice: - - [[1]] the <<>> must be compiled with <<>>, - - [[2]] while the rest of the sources must be compiled with the lower expected compatibility version of <<>>/<<>>. - - [] - - The preferred way to do this is by having 2 execution blocks, as described below: - - [[1]] default <<>> execution with <<>>, - - [[2]] additional custom <<>> execution with expected target compatibility. - - [] - - Notice that, in addition, JDK 9 only supports compilations for Java 6 and above, so projects wanting to be compatible with Java 5 or below need - to use two different JDKs for the 2 executions. With {{{/guides/mini/guide-using-toolchains.html}toolchains}} configuration, it is - quite easy to achieve this, even if a little bit more complex. - -* Java 6 to 8 Compatibility - - In case you want the project to be Java 6, 7 or 8 compatible, you can simply use JDK 9 for both execution blocks. - - The easiest way is to use Java 9 as the runtime for Maven, by setting <<>> before running <<>>. - But if you want to use an older Java runtime for Maven, you can use the maven-toolchain-plugin to specify the shared JDK - or a custom jdkToolchain and refer to the JDK 9 installation on your system. - -+------- - - [...] - - [...] - - - org.apache.maven.plugins - maven-compiler-plugin - ${project.version} - - - default-compile - - 9 - - - - - base-compile - - compile - - - - - module-info.java - - - - - - - 6 - - - 9 - - - - - [...] - - [...] - -+------- - -* Java 5 or below Compatibility - - Given that Maven 3 requires newer Java release at runtime, you'll absolutely need to use Toolchains to use a JDK different from - Maven runtime. - - You could add a jdkToolchain to do base-compile execution-block as well referring to JDK 5. - -+------- - - [...] - - [...] - - - org.apache.maven.plugins - maven-compiler-plugin - ${project.version} - - - default-compile - - 9 - - - - 9 - - - - - base-compile - - compile - - - - - module-info.java - - - - - - - 1.5 - 1.5 - - - [1.5,9) - - - - - [...] - - [...] - -+------- diff --git a/src/site/markdown/examples/module-info.md b/src/site/markdown/examples/module-info.md new file mode 100644 index 000000000..5c1e8329a --- /dev/null +++ b/src/site/markdown/examples/module-info.md @@ -0,0 +1,97 @@ + + +# Java 9+ projects with module-info + +If a project with a `module-info.java` file does not need to be compatible with Java 8 or earlier environment, +there is nothing special to do. + + +# Java 8 projects with module-info + +Projects that want to be compatible with older versions of Java (i.e, 8 or below bytecode and API), +but also want to provide a `module-info.java` for use on Java 9+ runtime, +must be aware that they need to call `javac` twice: + +1. the `module-info.java` must be compiled with `release` set to 9 or later, +2. the rest of the sources must be compiled with the lower expected compatibility version of source/target. + +A way to do this is by having two execution blocks, as described below: + +1. default `default-compile` execution with `release` set to 9 or later, +2. additional custom `base-compile` execution with expected target compatibility. + +The following snippet gives an example. +This snippet assumes that the JDK used by Maven supports the `--release 8` option. +It may not be the case for all JDKs, as newer JDKs may drop the support of Java versions that are too old. + +```xml + + [...] + + [...] + + + org.apache.maven.plugins + maven-compiler-plugin + ... + + + default-compile + + 9 + + + + + base-compile + + compile + + + 8 + + + + + + [...] + + [...] + +``` + +If the JDK used by Maven does not support the `--release 8` option, +then projects which want to be compatible with old Java versions need to use two different JDKs for the two executions. +Using a [toolchains](/guides/mini/guide-using-toolchains.html) configuration, it is possible to achieve this, even if more complex. +In above snippet, the following fragment: + +```xml + 8 +``` + +can be replaced by: + +```xml + 1.8 + 1.8 + + 1.8 + +``` From d123eaafbf3f182a3b0db4d5ab3baf2664bd8d2d Mon Sep 17 00:00:00 2001 From: Martin Desruisseaux Date: Tue, 1 Jul 2025 11:18:05 +0200 Subject: [PATCH 05/11] Port the "compile using different JDK" page from APT to Markdown with the following changes: * Remove the mention of `compilerVersion`, which is not supported anymore in plugin version 4. The version is either managed by the toolchain, or included in the path to the executable. --- .../compile-using-different-jdk.apt.vm | 112 ------------------ .../examples/compile-using-different-jdk.md | 95 +++++++++++++++ 2 files changed, 95 insertions(+), 112 deletions(-) delete mode 100644 src/site/apt/examples/compile-using-different-jdk.apt.vm create mode 100644 src/site/markdown/examples/compile-using-different-jdk.md diff --git a/src/site/apt/examples/compile-using-different-jdk.apt.vm b/src/site/apt/examples/compile-using-different-jdk.apt.vm deleted file mode 100644 index 0cee54aa8..000000000 --- a/src/site/apt/examples/compile-using-different-jdk.apt.vm +++ /dev/null @@ -1,112 +0,0 @@ - ------ - Compiling Sources Using A Different JDK - ------ - Edwin Punzalan - ------ - 2006-07-05 - ------ - -~~ 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. - -~~ NOTE: For help with the syntax of this file, see: -~~ http://maven.apache.org/doxia/references/apt-format.html - -Compiling Sources Using A Different JDK - -* Using Maven Toolchains - - The preferable way to use a different JDK is to use the toolchains mechanism. During the build of a project, Maven, - without toolchains, will use the JDK to perform various steps, like compiling the Java sources, generate the Javadoc, - run unit tests or sign JARs. Each of those plugins need a tool of the JDK to operate: <<>>, <<>>, - <<>>, etc. A toolchain is a way to specify the path to the JDK to use for all of those plugins in a - centralized manner, independent from the one running Maven itself. - - To set this up, refer to the {{{/guides/mini/guide-using-toolchains.html}Guide to Using Toolchains}}, which makes use - of the {{{/plugins/maven-toolchains-plugin/}Maven Toolchains Plugin}}. - - With the maven-toolchains-plugin you configure 1 default JDK toolchain for all related maven-plugins. - Since maven-compiler-plugin 3.6.0 when using with Maven 3.3.1+ it is also possible to give the plugin its own - toolchain, which can be useful in case of different JDK calls per execution block (e.g. the test sources require a - different compiler compared to the main sources). - -* Configuring the Compiler Plugin - - Outside of a toolchain, it is still possible to tell the Compiler Plugin the specific JDK to use during compilation. - Note that such configuration will be specific to this plugin, and will not affect others. - - The <<>> parameter can be used to specify the version of the - compiler that the plugin will use. However, you also need to set <<>> - to <<>> for this to work. For example: - -+------- - - [...] - - [...] - - - org.apache.maven.plugins - maven-compiler-plugin - ${project.version} - - true - true - - 1.3 - - - - [...] - - [...] - -+------- - - To avoid hard-coding a filesystem path for the executable, you can use a - property. For example: - -+------- - ${JAVA_1_4_HOME}/bin/javac -+------- - - Each developer then defines this property in - {{{http://maven.apache.org/ref/current/maven-settings/settings.html}settings.xml}}, - or sets an environment variable, so that the build remains portable. - -+------- - - [...] - - [...] - - compiler - - C:\Program Files\Java\j2sdk1.4.2_09 - - - - [...] - - compiler - - -+------- - - If you build with a different JDK, you may want to - {{{http://maven.apache.org/plugins/maven-jar-plugin/examples/manifest-customization.html} - customize}} the jar file manifest. diff --git a/src/site/markdown/examples/compile-using-different-jdk.md b/src/site/markdown/examples/compile-using-different-jdk.md new file mode 100644 index 000000000..1df2febd4 --- /dev/null +++ b/src/site/markdown/examples/compile-using-different-jdk.md @@ -0,0 +1,95 @@ + + +# Compiling Sources Using A Different JDK + +## Using Maven Toolchains + +The preferable way to use a different JDK is to use the toolchains mechanism. +During the build of a project, Maven, without toolchains, will use the JDK to perform various steps, +like compiling the Java sources, generate the Javadoc, run unit tests or sign JARs. +Each of those plugins need a tool of the JDK to operate: `javac`, `javadoc`, `jarsigner`, etc. +A toolchain is a way to specify the path to the JDK to use for all of those plugins in a centralized manner, +independent from the one running Maven itself. + +To set this up, refer to the [Guide to Using Toolchains](http://maven.apache.org/guides/mini/guide-using-toolchains.html), +which makes use of the [Maven Toolchains Plugin](http://maven.apache.org/plugins/maven-toolchains-plugin/). + +With the maven-toolchains-plugin you configure 1 default JDK toolchain for all related maven-plugins. +Since maven-compiler-plugin 3.6.0 when using with Maven 3.3.1+ it is also possible to give the plugin its own toolchain, +which can be useful in case of different JDK calls per execution block +(e.g. the test sources require a different compiler compared to the main sources). + + +## Configuring the Compiler Plugin + +Outside of a toolchain, it is still possible to tell the Compiler Plugin the specific JDK to use during compilation. +Note that such configuration will be specific to this plugin, and will not affect others. +If the `fork` parameter is set to `true`, the executable at the specified path will be used. +The following example uses a `JAVA_11_HOME` property which needs to be set by each developer, +as discussed in the next paragraph. + +```xml + + [...] + + [...] + + + org.apache.maven.plugins + maven-compiler-plugin + ... + + true + true + ${JAVA_11_HOME}/bin/javac + + + + [...] + + [...] + +``` + +The above example uses a `JAVA_11_HOME` property in order to avoid hard-coding a filesystem path for the executable. +Each developer defines this property in [settings.xml](http://maven.apache.org/ref/current/maven-settings/settings.html), +or sets an environment variable, so that the build remains portable. + +```xml + + [...] + + [...] + + compiler + + /usr/lib/jvm/java-11-openjdkk + + + + [...] + + compiler + + +``` + +If you build with a different JDK, you may want to +[customize the jar file manifest](http://maven.apache.org/plugins/maven-jar-plugin/examples/manifest-customization.html). From fac3d78d8b5e2e1e01b6ac22a380a24f53ac514e Mon Sep 17 00:00:00 2001 From: Martin Desruisseaux Date: Tue, 1 Jul 2025 11:25:54 +0200 Subject: [PATCH 06/11] Port the page about --source and --target from APT to Markdown with the following changes: * Insist that `--release` should be used instead. * Replace "JRE" term by "JDK" since the former is no longer used. * Use more recent Java version in the example. * Remove the sentence saying that the `release` property is replaced by `-source` and `-target` on Java 8 or earlier. This feature has been removed in plugin 4 since it requires Java 17. --- .../set-compiler-source-and-target.apt.vm | 91 ------------------- .../set-compiler-source-and-target.md | 78 ++++++++++++++++ 2 files changed, 78 insertions(+), 91 deletions(-) delete mode 100644 src/site/apt/examples/set-compiler-source-and-target.apt.vm create mode 100644 src/site/markdown/examples/set-compiler-source-and-target.md diff --git a/src/site/apt/examples/set-compiler-source-and-target.apt.vm b/src/site/apt/examples/set-compiler-source-and-target.apt.vm deleted file mode 100644 index 78ef38e10..000000000 --- a/src/site/apt/examples/set-compiler-source-and-target.apt.vm +++ /dev/null @@ -1,91 +0,0 @@ - ------ - Setting the -source and -target of the Java Compiler - ------ - Edwin Punzalan - ------ - 2006-07-05 - ------ - -~~ 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. - -~~ NOTE: For help with the syntax of this file, see: -~~ http://maven.apache.org/doxia/references/apt-format.html - -Setting the <<<-source>>> and <<<-target>>> of the Java Compiler - - (If you're are using version <<<3.13.0>>> or newer of the Compiler Plugin, use the recommended - {{{../examples/set-compiler-release.html}<<>> property}}.) - - Sometimes when you may need to compile a certain project to a different - version than what you are currently using. The <<>> can accept - such command using <<<-source>>> and <<<-target>>>. The Compiler Plugin - can also be configured to provide these options during compilation. - You have to set the version following {{{https://openjdk.org/jeps/223}Java's new Version-String Scheme (JEP 223)}}}. - - For example, if you want to use the Java 8 language features and also want the compiled classes to be compatible - with JVM 8 (former 1.8) you can either add the two following properties, which are the default property names - for the plugin parameters: - -+----- - - [...] - - 8 - 8 - - [...] - -+----- - - or configure the plugin directly: - -+----- - - [...] - - [...] - - - org.apache.maven.plugins - maven-compiler-plugin - ${project.version} - - 8 - 8 - - - - [...] - - [...] - -+----- - - <> Merely setting the <<>> option does not guarantee that your code actually runs on a JRE with the - specified version. The pitfall is unintended usage of APIs that only exist in later JREs which would make your code - fail at runtime with a linkage error. To avoid this issue, you can either configure the compiler's boot classpath - to match the target JRE, or use the - {{{http://www.mojohaus.org/animal-sniffer/animal-sniffer-maven-plugin/}Animal Sniffer Maven Plugin}} - to verify your code doesn't use unintended APIs, or better yet use the - {{{../examples/set-compiler-release.html}<<>> option supported since JDK 9}}. - Since plugin version <<<3.13.0>>> you can use the <<>> property also on JDK 8. - The compiler plugin will convert it to <<>> and <<>> automatically. - - In the same way, setting the <<>> option does not guarantee that your code actually compiles on a JDK with - the specified version. To compile your code with a specific JDK version, different than the one used to launch Maven, - refer to the {{{../examples/compile-using-different-jdk.html}Compile Using A Different JDK}} example. diff --git a/src/site/markdown/examples/set-compiler-source-and-target.md b/src/site/markdown/examples/set-compiler-source-and-target.md new file mode 100644 index 000000000..8fe32c3fa --- /dev/null +++ b/src/site/markdown/examples/set-compiler-source-and-target.md @@ -0,0 +1,78 @@ + + +# Setting the `--source` and `--target` of the Java Compiler + +**Using `--source` and `--target` options is not recommended.** +If you're are using version 3.13.0 or newer of the Compiler Plugin, +use the recommended [release](./set-compiler-release.html) configuration instead. + +Sometimes you may need to compile a certain project to a different version than what you are currently using. +The `javac` command can accept such options using `--source` and `--target`. +The Compiler Plugin can also be configured to provide these options during compilation. +You have to set the version following [Java's new Version-String Scheme (JEP 223)](https://openjdk.org/jeps/223). + +For example, if you want to use the Java 8 language features and also want the compiled classes to be compatible with JVM 8 (former 1.8), +you can either add the two following properties, which are the default property names for the plugin parameters: + +```xml + + [...] + + 8 + 8 + + [...] + +``` + +or configure the plugin directly: + +```xml + + [...] + + [...] + + + org.apache.maven.plugins + maven-compiler-plugin + ... + + 8 + 8 + + + + [...] + + [...] + +``` + +**Note:** Merely setting the `target` option does not guarantee that your code actually runs on a JDK with the specified version. +The pitfall is unintended usage of APIs that only exist in later JDKs which would make your code fail at runtime with a linkage error. +To avoid this issue, you can either configure the compiler's boot classpath to match the target JDK, +or use the [Animal Sniffer Maven Plugin](http://www.mojohaus.org/animal-sniffer/animal-sniffer-maven-plugin/) +to verify your code doesn't use unintended APIs, +or better yet use the [release](./set-compiler-release.html) option. + +In the same way, setting the `source` option does not guarantee that your code actually compiles on a JDK with the specified version. +To compile your code with a specific JDK version, different than the one used to launch Maven, +refer to the [Compile Using A Different JDK](./compile-using-different-jdk.html) example. From 58bb1545c77027aa2ce9a437400d978598b09799 Mon Sep 17 00:00:00 2001 From: Martin Desruisseaux Date: Tue, 1 Jul 2025 11:36:47 +0200 Subject: [PATCH 07/11] Port the "Compile Using Memory Allocation Enhancements" page with the following changes: * Version 4 of the Maven compiler plugin additionally accepts the 'k', 'M' and 'G' suffixes. --- .../compile-with-memory-enhancements.apt.vm | 56 ------------------- .../compile-with-memory-enhancements.md | 51 +++++++++++++++++ 2 files changed, 51 insertions(+), 56 deletions(-) delete mode 100644 src/site/apt/examples/compile-with-memory-enhancements.apt.vm create mode 100644 src/site/markdown/examples/compile-with-memory-enhancements.md diff --git a/src/site/apt/examples/compile-with-memory-enhancements.apt.vm b/src/site/apt/examples/compile-with-memory-enhancements.apt.vm deleted file mode 100644 index a4e6986d7..000000000 --- a/src/site/apt/examples/compile-with-memory-enhancements.apt.vm +++ /dev/null @@ -1,56 +0,0 @@ - ------ - Compile Using Memory Allocation Enhancements - ------ - Edwin Punzalan - ------ - 2006-07-05 - ------ - -~~ 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. - -~~ NOTE: For help with the syntax of this file, see: -~~ http://maven.apache.org/doxia/references/apt-format.html - -Compile Using Memory Allocation Enhancements - - The Compiler Plugin accepts configurations for <<>> and - <<>>. You can follow the example below to set the initial memory - size to 128MB and the maximum memory usage to 512MB: - -+----- - - [...] - - [...] - - - org.apache.maven.plugins - maven-compiler-plugin - ${project.version} - - true - 128m - 512m - - - - [...] - - [...] - -+----- \ No newline at end of file diff --git a/src/site/markdown/examples/compile-with-memory-enhancements.md b/src/site/markdown/examples/compile-with-memory-enhancements.md new file mode 100644 index 000000000..c9c2bc765 --- /dev/null +++ b/src/site/markdown/examples/compile-with-memory-enhancements.md @@ -0,0 +1,51 @@ + + +# Compile Using Memory Allocation Enhancements + +The Compiler Plugin accepts configurations for initial memory (`meminitial`) +and maximum memory (`maxmem`). +You can follow the example below to set the initial memory size to 128MB +and the maximum memory usage to 512MB: + +```xml + + [...] + + [...] + + + org.apache.maven.plugins + maven-compiler-plugin + ... + + true + 128m + 512m + + + + [...] + + [...] + +``` + +Version 4 of the Maven compiler plugin additionally accepts the 'k', 'M' (upper-case) +and 'G' suffixes for kilobytes, megabytes and gigabytes respectively. From eb0b62566bbdf47b76a32e35997e1a1cae8e2178 Mon Sep 17 00:00:00 2001 From: Martin Desruisseaux Date: Tue, 1 Jul 2025 11:41:28 +0200 Subject: [PATCH 08/11] Port the page about compiler arguments from APT to Markdown with no significant change in the text. --- .../examples/pass-compiler-arguments.apt.vm | 59 ------------------- .../examples/pass-compiler-arguments.md | 48 +++++++++++++++ 2 files changed, 48 insertions(+), 59 deletions(-) delete mode 100644 src/site/apt/examples/pass-compiler-arguments.apt.vm create mode 100644 src/site/markdown/examples/pass-compiler-arguments.md diff --git a/src/site/apt/examples/pass-compiler-arguments.apt.vm b/src/site/apt/examples/pass-compiler-arguments.apt.vm deleted file mode 100644 index 46057ff16..000000000 --- a/src/site/apt/examples/pass-compiler-arguments.apt.vm +++ /dev/null @@ -1,59 +0,0 @@ - ------ - Pass Compiler Arguments - ------ - Edwin Punzalan - ------ - 2006-07-05 - ------ - -~~ 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. - -~~ NOTE: For help with the syntax of this file, see: -~~ http://maven.apache.org/doxia/references/apt-format.html - -Pass Compiler Arguments - - Sometimes, you need to pass compiler arguments that are not handled by - the Compiler Plugin itself but are supported by the <<>> selected. - For such arguments, use the Compiler Plugin's <<>> parameter - The following example passes compiler arguments to the <<>> - compiler: - -+----- - - [...] - - [...] - - - org.apache.maven.plugins - maven-compiler-plugin - ${project.version} - - - -verbose - -Xlint:all,-options,-path - - - - - [...] - - [...] - -+----- diff --git a/src/site/markdown/examples/pass-compiler-arguments.md b/src/site/markdown/examples/pass-compiler-arguments.md new file mode 100644 index 000000000..b512d3a09 --- /dev/null +++ b/src/site/markdown/examples/pass-compiler-arguments.md @@ -0,0 +1,48 @@ + + +# Pass Compiler Arguments + +Sometimes, you need to pass compiler arguments that are not handled by the Compiler Plugin itself. +For such arguments, use the Compiler Plugin's `compilerArgs` parameter. +The following example passes compiler arguments to the `javac` compiler: + +```xml + + [...] + + [...] + + + org.apache.maven.plugins + maven-compiler-plugin + ... + + + -verbose + -Xlint:all + + + + + [...] + + [...] + +``` From b06289b52e380e966800ccce386d28e61f648908 Mon Sep 17 00:00:00 2001 From: Martin Desruisseaux Date: Tue, 1 Jul 2025 11:53:17 +0200 Subject: [PATCH 09/11] Port the page about --release from APT to Markdown with the following changes: * Put the current example in a "Maven 3" section. * Add a "Maven 4" section. --- .../apt/examples/set-compiler-release.apt.vm | 82 ----------------- .../markdown/examples/set-compiler-release.md | 92 +++++++++++++++++++ 2 files changed, 92 insertions(+), 82 deletions(-) delete mode 100644 src/site/apt/examples/set-compiler-release.apt.vm create mode 100644 src/site/markdown/examples/set-compiler-release.md diff --git a/src/site/apt/examples/set-compiler-release.apt.vm b/src/site/apt/examples/set-compiler-release.apt.vm deleted file mode 100644 index c0e57d7ed..000000000 --- a/src/site/apt/examples/set-compiler-release.apt.vm +++ /dev/null @@ -1,82 +0,0 @@ - ------ - Setting the --release of the Java Compiler - ------ - Mahmoud Anouti - ------ - 2019-12-20 - ------ - -~~ 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. - -~~ NOTE: For help with the syntax of this file, see: -~~ http://maven.apache.org/doxia/references/apt-format.html - -Setting the <<<--release>>> of the Java Compiler - - Starting with JDK 9, the <<>> executable can accept the <<<--release>>> - option to specify against which Java SE release you want to build the project. - For example, you have JDK 17 installed and used by Maven, but you want to - build the project against Java 8. - The <<<--release>>> option ensures that the code is compiled following the - rules of the programming language of the specified release, and that generated - classes target the release as well as the public API of that release. This - means that, unlike the old <<<-source>>> and <<<-target>>> options, - the compiler will detect and generate an error when using APIs that don't exist - in previous releases of Java SE. - - Since version 3.6 of the Compiler Plugin, this option can be provided either - via a property: - -+----- - - [...] - - 8 - - [...] - -+----- - - or by configuring the plugin directly: - -+----- - - [...] - - [...] - - - org.apache.maven.plugins - maven-compiler-plugin - ${project.version} - - 8 - - - - [...] - - [...] - -+----- - - <> The value in the <<>> parameter follows - {{{https://openjdk.org/jeps/223}Java's new Version-String Scheme (JEP 223)}}} adopted since Java 9. - As such, the release number does not start with 1.x anymore. Also note that the - supported <<>> targets include the release of the currently used JDK plus a limited number - of previous releases. diff --git a/src/site/markdown/examples/set-compiler-release.md b/src/site/markdown/examples/set-compiler-release.md new file mode 100644 index 000000000..500d6d324 --- /dev/null +++ b/src/site/markdown/examples/set-compiler-release.md @@ -0,0 +1,92 @@ + + +# Setting the `--release` of the Java Compiler + +Starting with JDK 9, the `javac` executable can accept the `--release` option +to specify against which Java SE release you want to build the project. +For example, you have JDK 17 installed and used by Maven, +but you want to build the project against Java 11. +The `--release` option ensures that the code is compiled following +the rules of the programming language of the specified release, +and that generated classes target the release as well as the public API of that release. +This means that, unlike the old `--source` and `--target` options, +the compiler will detect and generate an error when using APIs that don't exist in previous releases of Java SE. + +The preferred was to specify the release depends on the Maven version in use. + +## Maven 3 +Since version 3.6 of the Compiler Plugin, this option can be provided either via a property: + +```xml + + [...] + + 8 + + [...] + +``` + +or by configuring the plugin directly: + +```xml + + [...] + + [...] + + + org.apache.maven.plugins + maven-compiler-plugin + ... + + 11 + + + + [...] + + [...] + +``` + +## Maven 4 +Since version 4 of the compiler plugin, which requires Maven 4, +the preferred way to specify the release is together with the source declaration. +This is the recommended way because it makes the creation of +[multi-releases](../multirelease.html) projects easier. + +```xml + + [...] + + + 11 + + + [...] + +``` + +**Note:** The value in the `release` parameter follows +[Java's new Version-String Scheme (JEP 223)](https://openjdk.org/jeps/223) adopted since Java 9. +As such, the release number does not start with 1.x anymore. +Also note that the supported `release` targets include the release of the currently used JDK +plus a limited number of previous releases. From ba4efc6a0852bb8b4519e6130f8f30e7880616e8 Mon Sep 17 00:00:00 2001 From: Martin Desruisseaux Date: Tue, 1 Jul 2025 13:02:06 +0200 Subject: [PATCH 10/11] Port the `multirelease` file from APT to Markdown with the following changes: A significant change is that large parts of the explanation about JEP-238 ("forward compatibility problem") have been removed for the following reasons: * We assume that multi-releases is now known well enough. * The explanation used an obsolete example (Maven running on Java 6). * The section was showing how to NOT use multi-releases (using reflection), which may be more a distraction than a help for the purpose of this page. Removed most of the patterns for building a multi-releases project with Maven 3, because many of them were referencing external web sites which are not available anymore, or with content not obviously about multi-releases. In particular, removed the following references: * Reference to Animal Sniffer plugin, which is replaced by the `--release` option. * Page http://word-bits.flurg.com/multrelease-jars/ is not available anymore (404). * Page http://in.relation.to/2017/02/13/building-multi-release-jars-with-maven/ is blocked (security). * Page http://www.russgold.net/sw/2018/04/easier-than-it-looks/ refers to above-cited blocked page. Replaced "Maven module" by "Maven subproject" term for avoiding confusion with JPMS modules. Removed the "all IDEs can only have one JDK per Maven Project, whereas with multi release you want to specify it per source folder." This is not exactly true. We do not necessarily want different JDK, only different values for the `--release` option. Added a section about multi-releases JAR projects with Maven 4. --- src/site/apt/multirelease.apt | 220 ------------------------------ src/site/markdown/multirelease.md | 124 +++++++++++++++++ 2 files changed, 124 insertions(+), 220 deletions(-) delete mode 100644 src/site/apt/multirelease.apt create mode 100644 src/site/markdown/multirelease.md diff --git a/src/site/apt/multirelease.apt b/src/site/apt/multirelease.apt deleted file mode 100644 index 42aa53da5..000000000 --- a/src/site/apt/multirelease.apt +++ /dev/null @@ -1,220 +0,0 @@ - ------ - Multi Release - ------ - Robert Scholte - ------ - 2018-05-08 - ------ - -~~ 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. - -~~ NOTE: For help with the syntax of this file, see: -~~ http://maven.apache.org/doxia/references/apt-format.html - -Multi Release - - With {{{http://openjdk.java.net/jeps/238}JEP-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. - -* JEP-238 Introduction - -** The "forward compatibility" problem - - The problem this JEP is trying to solve is to make it possible to use new JDK features even though the codebase must stay compatible with earlier versions. - - Let's try to make this concrete with a real world example: In Java 7 <<>> was added, which was much better in File handling. In those days Maven still required Java 6 to run, however they wanted to make use of these new features when Maven was running on Java 7 or beyond. - - Up until Java 8 there were 2 solutions: - - [[1]] Compile with the targeted JDK (i.e. Java 6) and use reflection. You can ensure that the code is Java 6 compatible, but the reflection-part is hard to verify. - ---- - if ( isAtLeastJava7() ) { - Method toPathMethod = f.getClass().getMethod( "toPath" ); - Object toPathInstance = toPathMethod.invoke( f ); - Method isSymbolicLink = Class.forName( "java.nio.file.Files" ).getMethod( "isSymbolicLink" ); - ... - } - else { - // compare absoluteFile with canonicalFile - ... - } ---- - - [[2]] Compile with the required JDK (i.e. Java 7), but use source/target of the lowest version (i.e. 1.6). The danger here is that you cannot ensure that all code is Java 6 compatible. Depending on the code structure {{{https://www.mojohaus.org/animal-sniffer/}Animal Sniffer}} might help. - ---- - if ( isAtLeastJava7() ) { - return Files.isSymbolicLink( f.toPath() ); - } - else { - // compare absoluteFile with canonicalFile - ... - } ---- - - [] - -** The "forward compatibility" solution - ---- -A.class -B.class -C.class -D.class -META-INF/MANIFEST.MF { Multi-Release: true } - versions/9/A.class - B.class - 10/A.class - C.class - ---- - - With the <<>> flag in the MANIFEST file, the Java runtime will also look inside <<>> for version specific classes, otherwise only the base classes are used. - -* Challenges - - The theory behind multi release jars is quite simple, but in practice it can become quite complex. You must ensure that all classes stay in sync; if you add a method to one class, don't forget to add it to the other classes as well. - There are some options which should reduce problems at this level: - Let all multirelease classes implement an interface and in the basecode instantiate the class but only call the interface methods. - The best is to test the *jar* with all targeted Java versions. - You should think twice before turning your jar into a multi release jar, because such jars can be hard to read, maintain and test. In general applications don't need this, unless it is a widely distributed application and you don't control the targeted Java runtime. Libraries should make a decision based on: do I need this new Java feature? Can I make this Java version the new requirement? Would it be acceptable to solve this with an else/if-statement as mentioned in the first paragraph? - - There are a couple of important facts one should know when creating Multi Release jars. - - * The Java compiler must be called for every different version. The solutions solve this either by having multiple Maven Projects/Modules or by adding extra compiler execution-blocks to the POM (like {{{./examples/module-info.html}older projects with module-info}}). - - * The <<>> attribute is only recognized when the classes are in a jar. In other words, you cannot test the classes put in <<>>. - - * Up until the moment of writing all IDEs can only have one JDK per Maven Project, whereas with multi release you want to specify it per source folder. - - [] - -Pattern 1: {{{https://github.com/hboutemy/maven-jep238}Maven Multimodule}} - - This is the first pattern provided by the Maven team themselves. They had the following requirements: - - * Only one Maven call to compile, test and package the Multi Release jar - - * It must work with IDEs - - * Developers should not change their way of work / simple configuration - - [] - - The only solution to cover the first two bullets was to split the code into a Maven multimodule project. - Now every Maven module is just a standard Maven project with close to no specific adjustments in the pom. - There are several ways you can run this project: - - * Use the highest required version of the JDK to build the project. You can use <<>> to ensure the code only uses matching code and syntax. Since the version-code is isolated you can run surefire with a higher Java runtime. - - * Use toolchains if you really want to compile and test with the matching Java version. - - [] - - The downside it that a hierarchical structure is required even though the result is just 1 artifact. - -Pattern 2: {{{http://word-bits.flurg.com/multrelease-jars/}Multi Project}} - - This solution is a response to the previous Maven multimodule setup. The requirements are almost the same - - * Do not require the project to switch to a multi-module format - - * Developers should not change their way of work / simple configuration - - [] - - The first requirements implies that the projects now are separate Maven projects. - One Maven project contains the base-code and in the end this will also be the multirelease jar. - When building such project for the first time, you'll need to call Maven at least 3 times: first the base needs to be compiled, next all version specific projects must be built and finally the main project needs to be built again, now including the version specific classes extracted from their jars. - This setup is compact, but has cyclic dependencies. This requires some tricks and makes releasing a bit more complicated. - Another downside is that you must install SNAPSHOTs to your local repository and when doing a release it requires 2 releases of the base project, one to prepare for the multirelease-nine and one with the released multirelease-nine. - -Pattern 3: Single Project - - By now there are 3 solutions, each inspired by their previous version. - - Main goal: - - * Do not require the project to switch to a multi-module format - - * Only one Maven call to compile and package the Multi Release jar - - [] - -* {{{http://in.relation.to/2017/02/13/building-multi-release-jars-with-maven/}Single Project}} - - In this case everything stays inside one Maven project. - Every specific Java version gets its own source folder and output folder, and just before packaging they are combined. - What's not covered is how to test every class. - -* {{{http://www.russgold.net/sw/2018/04/easier-than-it-looks/}Multi-Release Parent}} - - This approach replaces the maven-ant-plugin with extra exucution blocks in the maven-compiler-plugin. It has been setup as a parent, so other projects can use it. It uses toolchains to be able to build all classes with their matching Java version, so you always get the multi release jar. Because of the huge configuration and since Maven doesn't support mixins yet, it makes sense to put it all in a parent. - However, at the same time surefire is only called once. - -* {{{https://github.com/codehaus-plexus/plexus-languages}CI-server}} - - This approach reduces the previous solution by only specifying execution blocks for sources for a specific Java version. It doesn't use toolchains, but the JDK used to run Maven. This means that only the sources up to the specific Java version are compiled and tested. - This solution relies heavily on a CI-server where every targeted Java version is available. If the CI-server succeeds, then all classes are tested with their matching Java version. - -Pattern 4: {{{https://github.com/metlos/multi-release-jar-maven-plugin}Maven extension + plugin}} - - This approach introduces a new packaging type and an extra plugin takes care of the multiple executions of the maven-compiler-plugin, but these are now - handled by the <<>> of the <<>>. What's not covered is how to test every class. - -Patterns Summary - - For every pattern there are integration tests created, based on the same set of sourcefiles. See {{https://github.com/apache/maven-compiler-plugin/tree/master/src/it/multirelease-patterns}} - -*-------------------------------*-----------------------*-------------------------*---------------------------*------------------------------*--------------------------------* -|| || Maven Multimodule || Multi Project || Single project (runtime) || Single project (toolchains) || Maven extension+plugin || -*-------------------------------+-----------------------+-------------------------+---------------------------+------------------------------*--------------------------------+ -| # projects | 1 | 1 + #javaVersions | 1 | 1 | 1 | -*-------------------------------+-----------------------+-------------------------+---------------------------+------------------------------*--------------------------------+ -| # builds to package | 1 | 2 + #javaVersions | 1 | 1 | 1 | -*-------------------------------+-----------------------+-------------------------+---------------------------+------------------------------*--------------------------------+ -| # builds/project to test | 1 | 1 | #javaVersions | 1 | N/A (a) | -*-------------------------------+-----------------------+-------------------------+---------------------------+------------------------------*--------------------------------+ -| Simple Maven Project Layout | No | Yes | Yes | Yes | Yes | -*-------------------------------+-----------------------+-------------------------+---------------------------+------------------------------*--------------------------------+ -| Additional POM adjustments(b) | 1 (c) | #javaVersions(d) | #javaVersions(e) | ??(f) | #javaVersions(g) | -*-------------------------------+-----------------------+-------------------------+---------------------------+------------------------------*--------------------------------+ -| Include module descriptor | No (h) | No (h) | Yes | Yes | Yes | -*-------------------------------+-----------------------+-------------------------+---------------------------+------------------------------*--------------------------------+ -| IDE support (i) | Yes | Yes | No | No | No | -*-------------------------------+-----------------------+-------------------------+---------------------------+------------------------------*--------------------------------+ - - (a) Project can only be executed with highest required JDK, hence you can't test the code for all JDKs - - (b) Additional POM adjustments: # of executions added to the default lifecycle. This reflects the complexity of the POM. - - (c) Maven multimodule uses maven-assembly-plugin to assemble to multirelease jar - - (d) Multi project uses the maven-dependency-plugin to unpack java specific dependency to its matching outputDirectory - - (e) There's a profile for every Java version required which contains an extra execution-block for that Java version. - - (f) - - (g) Maven extension+plugin hides the multiple executions in the <<>> configuration - - (h) Requires a --patch-module on a dependency - - (i) IDE Support: All classes are recognized and can be tested within the IDE. diff --git a/src/site/markdown/multirelease.md b/src/site/markdown/multirelease.md new file mode 100644 index 000000000..1ce0a55f3 --- /dev/null +++ b/src/site/markdown/multirelease.md @@ -0,0 +1,124 @@ + + +# Multi Release + +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-releases project are organized like below: + +``` +. +├─ A.class +├─ B.class +├─ C.class +├─ D.class +└─ META-INF + ├─ MANIFEST.MF { Multi-Release: true } + └─ versions + ├─ 9 + │ ├─ A.class + │ └─ B.class + └─ 10 + ├─ A.class + └─ C.class +``` + +With the `Multi-Release: true` flag in the `MANIFEST.MF` file, +the Java runtime will also look inside `META-INF/versions` for version specific classes, +otherwise only the base classes are used. + + +## Challenges + +The theory behind multi release JARs is quite simple, but in practice it can become quite complex. +You must ensure that all classes stay in sync; +if you add a method to one class, don't forget to add it to the other classes as well. +The best is to test the JAR with all targeted Java versions. +You should think twice before turning your JAR into a multi release JAR, +because such JARs can be hard to read, maintain and test. +In general applications don't need this, unless it is a widely distributed application and you don't control the targeted Java runtime. +Libraries should make a decision based on: do I need this new Java feature? Can I make this Java version the new requirement? + +There are a couple of important facts one should know when creating Multi Release JARs: + +* The Java compiler must be called for every different version. + With Maven 3, it requires either having multiple Maven Projects/Modules or adding extra compiler execution-blocks to the POM + (like [older projects with module-info](./examples/module-info.html)). +* The `Multi-Release: true` attribute is only recognized when the classes are in a JAR. + In other words, you cannot test the classes put in `target/classes/META-INF/versions/${release}/` with Maven 3. + + +## Maven 3 + +Maven 3 proposed many different patterns for building multi-releases project. +One pattern is to create a sub-project for each version. +The project needs to be build with the highest required version of the JDK, +and a `--release` option is specified in each sub-project. +If desired, toolchains can be used for compiling and testing with the matching Java version. +This pattern is demonstrated in the [maven-jep238](https://github.com/hboutemy/maven-jep238) project example. +The downside it that a hierarchical structure is required even though the result is just 1 artifact. + +Another pattern is to use the [Multi Release JAR Maven Plugin](https://github.com/metlos/multi-release-jar-maven-plugin). +This approach introduces a new packaging type and an extra plugin takes care of the multiple executions of the Maven Compiler Plugin, +but these are now handled by the `perReleaseConfiguration` of the `multi-release-jar-maven-plugin`. +What's not covered is how to test every class. + +See [Maven Compiler Plugin integration tests](https://github.com/apache/maven-compiler-plugin/tree/master/src/it/multirelease-patterns) +for examples of small projects using the following patterns: + +* Maven sub-projects +* Multi projects +* Single project (runtime) +* Single project (toolchains) +* Maven extension + plugin + + +## Maven 4 + +Building a multi-releases project is much easier with version 4 of the Maven Compiler Plugin. +The source code for all versions are placed in different directories of the same Maven project. +These directories are declared together with the Java release like below: + +```xml + + [...] + + + src/main/java + 17 + + + src/main/java_21 + 21 + + + test + src/test/java + 17 + + [...] + +``` + +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 `` 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. From 9e2d877da417aa7286413e8dae1ea3e78f373704 Mon Sep 17 00:00:00 2001 From: Martin Desruisseaux Date: Tue, 1 Jul 2025 13:12:44 +0200 Subject: [PATCH 11/11] Port the index from APT to Markdown with the following changes: * Remove the sentence saying that Java 8 is the default version. Version 4 of the plugin does not set a default version anymore. --- src/site/apt/index.apt.vm | 86 -------------------------------------- src/site/markdown/index.md | 68 ++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 86 deletions(-) delete mode 100644 src/site/apt/index.apt.vm create mode 100644 src/site/markdown/index.md diff --git a/src/site/apt/index.apt.vm b/src/site/apt/index.apt.vm deleted file mode 100644 index dc2b27c36..000000000 --- a/src/site/apt/index.apt.vm +++ /dev/null @@ -1,86 +0,0 @@ - ------ - Introduction - ------ - Edwin Punzalan - ------ - 2013-07-22 - ------ - -~~ 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. - -~~ NOTE: For help with the syntax of this file, see: -~~ http://maven.apache.org/doxia/references/apt-format.html - -${project.name} - - The Compiler Plugin is used to compile the sources of your project. The - default compiler used to compile Java sources is <<>>. - If you want to use another compiler, refer to the {{{./non-javac-compilers.html} guide: Using Non-Javac Compilers}}. - - At present the default <<>> and the default <<>> - setting are both <<<8>>>, independently of the JDK you run Maven with. - You are highly encouraged to change these defaults by setting the <<>> option as described in the - {{{./examples/set-compiler-release.html}guide: Compile Using The <<<--release>>> javac Option}}. - - <> - -* Goals Overview - - The Compiler Plugin has two goals. Both are already bound to their proper - phases within the Maven Lifecycle and are therefore, automatically executed - during their respective phases. - - * {{{./compile-mojo.html}compiler:compile}} is bound to the compile phase and - is used to compile the main source files. - - * {{{./testCompile-mojo.html}compiler:testCompile}} is bound to the - test-compile phase and is used to compile the test source files. - -* Usage - - General instructions on how to use the Compiler Plugin can be found on the {{{./usage.html}usage page}}. Some more - specific use cases are described in the examples given below. - - In case you still have questions regarding the plugin's usage, please have a look at the {{{./faq.html}FAQ}} and feel - free to contact the {{{./mailing-lists.html}user mailing list}}. The posts to the mailing list are archived and could - already contain the answer to your question as part of an older thread. Hence, it is also worth browsing/searching - the {{{./mailing-lists.html}mail archive}}. - - If you feel the plugin is missing a feature or has a defect, you can file a feature request or bug report in our - {{{./issue-management.html}issue tracker}}. When creating a new issue, please provide a comprehensive description of your - concern. Especially for fixing bugs it is crucial that the developers can reproduce your problem. For this reason, - entire debug logs, POMs or most preferably little demo projects attached to the issue are very much appreciated. - Of course, patches are welcome, too. Contributors can check out the project from our - {{{./scm.html}source repository}} and will find supplementary information in the - {{{http://maven.apache.org/guides/development/guide-helping.html}guide to helping with Maven}}. - -* Examples - - To provide you with better understanding on some usages of the Compiler - Plugin, you can take a look into the following examples: - - * {{{./examples/compile-using-different-jdk.html}Compile using A Different JDK}} - - * {{{./examples/set-compiler-release.html}Compile Using The --release javac Option}} - - * {{{./examples/compile-with-memory-enhancements.html}Compile Using Memory Allocation Enhancement}} - - * {{{./examples/pass-compiler-arguments.html}Pass Compiler Arguments}} - - [] diff --git a/src/site/markdown/index.md b/src/site/markdown/index.md new file mode 100644 index 000000000..54d10e12e --- /dev/null +++ b/src/site/markdown/index.md @@ -0,0 +1,68 @@ + + +The Compiler Plugin is used to compile the sources of your project. +The default compiler used to compile Java sources is `javac`. +If you want to use another compiler, refer to the [using Non-Javac Compilers](/non-javac-compilers.html) page. + +**NOTE:** To know more about the JDK `javac`, please see the +[tool guide](https://docs.oracle.com/en/java/javase/24/docs/specs/man/javac.html). + +# Goals Overview + +The Compiler Plugin has two goals. +Both are already bound to their proper phases within the Maven Lifecycle and are therefore, +automatically executed during their respective phases. + +* [compiler:compile](./compile-mojo.html) is bound to the compile phase and is used to compile the main source files. +* [compiler:testCompile](./testCompile-mojo.html) is bound to the test-compile phase and is used to compile the test source files. + +# Usage + +General instructions on how to use the Compiler Plugin can be found on the [usage page](./usage.html). +Some more specific use cases are described in the examples given below. + +In case you still have questions regarding the plugin's usage, please have a look at the [FAQ](./faq.html) +and feel free to contact the [user mailing list](./mailing-lists.html). +The posts to the mailing list are archived and could already contain the answer to your question as part of an older thread. +Hence, it is also worth browsing/searching the [mail archive](./mailing-lists.html). + +If you feel the plugin is missing a feature or has a defect, +you can file a feature request or bug report in our [issue tracker](./issue-management.html). +When creating a new issue, please provide a comprehensive description of your concern. +Especially for fixing bugs it is crucial that the developers can reproduce your problem. +For this reason, entire debug logs, POMs or most preferably little demo projects attached to the issue are very much appreciated. +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). + +# Examples + +To provide you with better understanding on some usages of the Compiler Plugin, +you can take a look into the following examples: + +* [Annotation processors](./examples/annotation-processor.html) +* [Arguments related to Java Platform Module System](./examples/jpms_args.html) +* [Compile using a different JDK](./examples/compile-using-different-jdk.html) +* [Compile using a non-javac compilers](./examples/non-javac-compilers.html) +* [Compile using the --source and --target javac options](./examples/set-compiler-source-and-target.html) +* [Compile using the --release javac option](./examples/set-compiler-release.html) +* [Compile using memory allocation enhancements](./examples/compile-with-memory-enhancements.html) +* [Java 9+ projects with module-info](./examples/module-info.html) +* [Pass compiler arguments](./examples/pass-compiler-arguments.html)