[MSHADE-265] - Add module-info merging support - #829
Conversation
6cbc929 to
38ac043
Compare
90dc6e4 to
4cb31a5
Compare
ea84628 to
82abdc8
Compare
82abdc8 to
b3653b4
Compare
|
Rebased. |
b3653b4 to
a6a69e6
Compare
|
Rebased. |
Add opt-in merging for root and multi-release module descriptors while preserving the primary module boundary. Cover relocation, services, modular-floor handling, filtering failures, Maven 3/4 compatibility, and reactor output directories during manifest processing. Keep the PR-owned tests aligned with the JUnit 5 migration on master. Fixes apache#629. Fixes apache#581. Fixes apache#588.
a6a69e6 to
4569d75
Compare
| jos.putNextEntry(jarEntry); | ||
| outputManifest.write(jos); | ||
| } finally { | ||
| forceMultiRelease = false; |
There was a problem hiding this comment.
This worries me a bit. It suggests there's a specific order to call methods, and thread safety might be in play. Maybe forceMultiRelease and forceAutomaticModuleName should be arguments instead of fields. Not sure, but worth digging into
There was a problem hiding this comment.
I have made a change to limit the fields change only around the call to modifyOutputStream.
Threading should not be a problem. The transformers should be per-mojo invocation and within the invocation it is all a single thread. Unless the plugin itself spawns some threads.
elharo
left a comment
There was a problem hiding this comment.
The more I look at this the more unsure I am. The PR might be 100% correct and exactly what we need to do, but I don't know. What does shading a modular application even mean? Can we make shading work with JPMS, or is this something we fundamentally should not do?
Others might understand the issues involved here better than me.
| manifest = jarFile.getManifest(); | ||
| } | ||
| } | ||
| if (manifest != null |
There was a problem hiding this comment.
this might be able to be extracted to a private method and then pushed into the try blocks
| /** | ||
| * Controls how module descriptors are handled while shading. | ||
| */ | ||
| public enum ModuleInfoMode { |
There was a problem hiding this comment.
do enums have to be public?
| */ | ||
| public enum ModuleInfoMode { | ||
| /** Discard module descriptors, retaining the historical behavior. */ | ||
| discard, |
There was a problem hiding this comment.
These are usually UPPER CASE
| # Merging Java Module Descriptors | ||
|
|
||
| By default, the plugin discards every root and versioned `module-info.class` from the inputs. This preserves the | ||
| historical behavior: an unmodified descriptor would describe the original artifact rather than the contents of the |
There was a problem hiding this comment.
would describe --> describes
| ``` | ||
|
|
||
| Merge mode models the shaded JAR as if the retained, relocated source files had been compiled together as one module. | ||
| The primary artifact remains authoritative for the module name, version, main class, and, by default, the public |
There was a problem hiding this comment.
Is this right? Shouldn't a shaded jar change the module name? One purpose of shading is to allow multiple versions to exists in the classpath at the same time.
Summary
Add opt-in merging of Java module descriptors with:
The default remains
discard, preserving the plugin's existing behavior.The merge follows a source-amalgamation model: the primary artifact supplies the
module identity, while the shaded contents are treated as if their sources had
been relocated and compiled into that module. By default, the primary module's
exports and opens remain its public boundary. Users can opt into the effective
boundary of embedded modules or add explicit exports, opens, requirements, and
service uses where source-level intent cannot be inferred safely.
The processor:
requirements that collide with inactive descriptor or filename-derived names;
and materializing retained packages from embedded open modules when boundary
merging is requested;
automatic modules;
actionable guidance when dynamic service use cannot be inferred;
descriptor view used for merging;
ct.symandjmodsfrom a selected JDK,with optional toolchain requirements for release-aware analysis; and
Multi-release inputs are merged as cumulative release views. The implementation
rebuilds
ModulePackages, validates the invariants required of versioned moduledescriptors, and raises the modular floor when a provider or public-boundary
change cannot be represented at an earlier release. Earlier releases then retain
an automatic-module bridge with a stable
Automatic-Module-Name.Manifest processing now also accepts reactor output directories. Maven can expose
a reactor dependency as
target/classeswhen separate lifecycle tasks such aspackage testare requested. The manifest pre-scan reads a directory manifestwhen present, instead of attempting to open the directory as a JAR.
Documentation covers the defaults, public-boundary modes, explicit overrides,
toolchain selection, dynamic service use, and modular-floor behavior.
Fixes #629.
Fixes #581.
Fixes #588.
JIRA: MSHADE-265,
MSHADE-215
Validation
mvn test: 104 tests run, zero failures; one skipped.mvn test: 104 tests run, zero failures; 14 modular-runtime tests skipped.mvn -Prun-its verify: 86 integration projects passed, one skipped by itsJRE-version condition.
module-info-mergeproject passed when the built plugin was runwith Maven 3.6.3, current Maven 3.x, and Maven 4.
MSHADE-215project fails with Shade 3.6.2 and passes with thebranch build under Maven 3.6.3, current Maven 3.x, and Maven 4.
21 JVM and Maven 3.9.16; the branch build completed successfully in the same
environment.
mvn sitepassed.jar --validate,jar --describe-module,and
jdeps --check.Following this checklist to help us incorporate your
contribution quickly and easily:
for the change (usually before you start working on it). Trivial changes like typos do not
require a JIRA issue. Your pull request should address just this issue, without
pulling in other changes.
[MSHADE-XXX] - Fixes bug in ApproximateQuantiles,where you replace
MSHADE-XXXwith the appropriate JIRA issue. Best practiceis to use the JIRA issue title in the pull request title and in the first line of the
commit message.
mvn clean verifyto make sure basic checks pass. A more thorough check willbe performed on your pull request automatically.
mvn -Prun-its clean verify).If your pull request is about ~20 lines of code you don't need to sign an
Individual Contributor License Agreement if you are unsure
please ask on the developers list.
To make clear that you license your contribution under
the Apache License Version 2.0, January 2004
you have to acknowledge this by using the following check-box.
I hereby declare this contribution to be licenced under the Apache License Version 2.0, January 2004
In any other case, please file an Apache Individual Contributor License Agreement.