Skip to content

Option to only allow explicit dependencies in unpack goal #1542

@PayBas

Description

@PayBas

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:

  1. 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.
  2. The elements are more "familiar", since it uses the exact same XML elements as a regular <dependency>.
  3. unpack actually fails when the artifact is not found, whereas unpack-dependencies simply continues silently while doing nothing, leading to harder to diagnose failures in later steps.
  4. unpack works 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions