-
Notifications
You must be signed in to change notification settings - Fork 185
Description
New feature, improvement proposal
I've noticed a pervasive negative behavior throughout larger multi-module Maven projects for years now, and it has to do with the unpack goal.
Our developers tend to find this:
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>mega.corp</groupId>
<artifactId>some-module</artifactId>
<version>1.0.0</version>
<classifier>resources</classifier>
<type>zip</type>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>more intuitive than (and therefore preferable to):
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeGroupIds>mega.corp</includeGroupIds>
<includeArtifactIds>some-module</includeArtifactIds>
<includeClassifiers>resources</includeClassifiers>
<includeTypes>zip</includeTypes>
</configuration>
</execution>
</executions>
</plugin>And I don't blame them:
- It feels more "exact", since there is no chance of including more artifacts than intended. An
<artifactItem>(or even just<artifact>) is guaranteed to only target 1 artifact. - The elements are more "familiar", since it uses the exact same XML elements as a regular
<dependency>. unpackactually fails when the artifact is not found, whereasunpack-dependenciessimply continues silently while doing nothing, leading to harder to diagnose failures in later steps.unpackworks even if the<artifactItems>(or<artifact>) entries are not defined as<dependencies>, so in the minds of our developers, there is no need to define the artifacts as<dependencies>. This keeps the POM-file nice and short, which is good, right? DRY principles etc.
I know that in this example, point 3 can be somewhat worked around by using <classifier>+<type>+<failOnMissingClassifierArtifact> instead of <includeClassifiers>+<includeTypes>, but you'd only know this by reading the plugin documentation. And like I said: intuitiveness.
But my major problem is point 4: unpack works even if the <artifactItems> entries are not defined as <dependencies>.
Problem
I know this is by design and perfectly valid, but it has some very nasty side-effects. Primarily that <artifactItems> are invisible to both the Maven reactor and the maven-dependency-plugin itself! This means that the artifacts will not be detected by dependency:tree, nor by dependency:go-offline, nor by SBOM generators such as CycloneDX.
And in a multi-module Maven build where <artifactItems> can refer to artifacts from different modules in the same tree, the Maven reactor also doesn't detect <artifactItems> as inter-module dependencies. So they will not be taken into account when determining the reactor build order. This issue is exacerbated when using multi-threaded builds such as when using the Maven Daemon, which can lead to sporadic build failures since the order isn't deterministic.
Request
Either: Have all <artifactItems> as defined in the unpack execution configuration automatically appended to the detected dependencies list. I think this would need to happen very early in the Maven project discovery cycle for the reactor to be able to use these extra entries when determining project build order. This might prove to be very difficult to implement, and would entail breaking change behavior.
Or: Provide some way to force all <artifactItems> to be explicitly defined as <dependencies> as well. Perhaps a <requireExplicitDependencies> boolean parameter can be added, which we can set in our parent POMs.
Or: Create a maven-enforcer-plugin rule that checks whether all <artifactItem> (and <artifact>) entries are actually present in the dependencies of the project. Perhaps augmented by some coordinate exclusion logic for edge cases.