Migrate from Maven Archiver to standard "jar" tool

Open
#495 4 comments 0 reactions 1 assignee View on GitHub

@desruisseaux is already working on this.

Since Nov 10, 2025.

Assessment

This issue has not been assessed yet.

Description

enhancement
New feature, improvement proposal

This is a description of a work being done as part of Full Java Module Support effort. If the principle is accepted, a pull request will be submitted later. This issue is for collecting feedbacks in the meantime.

This work is a refactoring of the Maven JAR plugin for using the standard jar tool instead of Maven Archiver. It can be done by using 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 with the addition of a special handling of 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, 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 (available since Java 9), it may be time to abandon our manual creation of a JAR file and rely fully on the jar tool instead.

Benefits

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 would be fixed by this proposal. Note that if this verification is not desired, Maven users can disable it by setting the detectMultiReleaseJar plugin option to false.

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.

Other options such as --module-version and --hash-modules which are not yet used in the current plugin will become used in a future version, especially since security is becoming more and more a concern.

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 would be 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, which can traverse the directory tree itself.

Prototype

If accepted, the pull request would be created from this clone after all integration tests pass (this is not yet the case at the time of writing this issue).

Dominant language
Java
Stars
92
Forks
84
Avg merge
15h 55m
Merged PRs (30d)
7

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from apache/maven-jar-plugin

All issues in apache/maven-jar-plugin

Similar issues

More Java issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.