desruisseaux opened a new pull request, #508: URL: https://github.com/apache/maven-jar-plugin/pull/508
This is a major refactoring of the Maven JAR Plugin for using the standard `jar` tool instead of Maven Archiver. The standard tool is available through the `java.util.spi.ToolProvider` interface, which was introduced in Java 9. Since Maven 4 upgraded its requirement from Java 8 to Java 17, the use of that interface is no longer problematic. # Rational In early Java days, the `jar` tool was equivalent to a `zip` command with a different syntax and a little bit of special processing for the `META-INF/MANIFEST.MF` file. Because of this quasi-equivalence, it was not difficult to create JAR files ourselves using any library capable to write ZIP files. This is what Maven Archiver does, together with supporting other archive formats. But today, the `jar` tool became more sophisticated. It now includes options for verifying the consistency of multi-release JAR files, options for updating `module-info.class`, provides security features specific to Java, _etc._. This evolution can be seen in the ["Modular JAR files" section of the Maven Plugin documentation](https://maven.apache.org/plugins/maven-jar-plugin/usage.html#Modular_JAR_files), which states that the plugin uses the `jar` tool for updating the JAR file in a way that the Maven Archiver can't do easily. Therefore, since Maven 4 requires Java 17 and since that Java version gives us an easy access to the `jar` tool through the `java.util.spi.ToolProvider` interface, it may be time to abandon our manual creation of a JAR file and rely fully on the `jar` tool instead. # Benefits ## Safer multi-release JAR files In a multi-release JAR file, blindingly storing the content of `META-INF/versions/` directories as if they were ordinary resources is not equivalent to using the `jar --release` option. The difference is that in the latter case, the `jar` tool performs some consistency checks. This issue was independently reported by user in #484, which is fixed by this pull request. Note that if this verification is not desired, Maven users can disable it by setting the `detectMultiReleaseJar` plugin option to `false`. ## Main class managed by the `jar` tool In a modular JAR file, it is no longer sufficient to declare the main class in the `Main-Class` entry of the `MANIFEST.MF` file. The main class needs to be specified by the `--main-class` option of the `jar` tool, which will update `module-info.class`. For compatibility reason the Maven JAR plugin gets the option value from that manifest entry, but internally the use of the `jar` tool is mandatory. ## Options not yet supported by the plugin This approach allows to add a `<jarArgs>` configuration option, similar to the `<compilerArgs>` in the Maven Compiler Plugin. Such option would allow developers to use new tool arguments before they are supported by the plugin. Examples of options not yet supported by the plugin are `--module-version` and `--hash-modules`. Explicit support for those options could be added in a future plugin version, especially since security is becoming more and more a concern. ## Easier debugging and toolchain This approach makes easy to generate a `target/jar.args` file when the build fails or when Maven is run in verbose mode. This is similar to the compiler plugin generating a `target/javac.args` file. This file allows the user to test easily on the command-line, which makes debugging faster. Likewise, the options can also be passed to another tool, which makes easier to resolve #439 as well. # Behavioral changes The plugin behaviour after the proposed refactoring is different than version 3 in the following aspects: ## Removal of default `**/package.html` excludes The current plugin version uses an undocumented `**/package.html` default excludes. This default seems to exist since the initial revision in March 2004, but I saw no explanation for this oddity. This default is not mentioned in the documentation. The removal of this oddity is necessary for allowing the proposed new plugin implementation to specify only some root directories to the `jar` tool, since the tool can traverse the directory tree itself. ## Automatic use of `MANIFEST.MF` After this refactor, the plugin automatically uses the `META-INF/MANIFEST.MF` file found in the `classes` directory. Before this refactor, the plugin used that file only if explicitly specified in the `<manifestFile>` archive configuration. The previous policy was discussed in #255. The new policy is a natural consequence of the way that the JAR plugin is reimplemented, and also more useful in the context of multi-module (in Java module sense) projects since each module could contain its own `MANIFEST.MF` file. ## Multi-module projects The refactoral support multi-module projects, including projects that are both multi-module and multi-release, as discussed in https://github.com/apache/maven-compiler-plugin/pull/998. # Dependencies This pull request depends on a Maven release which include the following pull requests: * https://github.com/apache/maven/pull/11425 * https://github.com/apache/maven/pull/11549 * https://github.com/apache/maven-compiler-plugin/pull/998 -- 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]
