Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Maven packaging, transitive dependencies aren't included

I'm playing around with a custom Maven 3 packaging plugin for some non-java artifacts, and having an issue getting transitive dependencies to work. I've got three projects defined, model, model-impl, and cli, with dependencies like this:

cli
  model-impl
    model

My custom lifecycle plugins are being called in each project, and I can successfully build model and model-impl. For each of those projects, the expected artifacts are being stored in my local repository. cli however is failing because I don't get model as a dependency in my Mojo. I'm not completely sure that this is a problem in my code though, because even using mvn dependency:dependency-tree doesn't show the full dependency hierarchy:

[INFO] Scanning for projects...
[INFO]
[INFO] ----------------------< com.corp.nodes:myproj-cli >-----------------------
[INFO] Building myproj Test 1.0.0-SNAPSHOT
[INFO] --------------------------------[ myproj ]--------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ myproj-cli ---
[INFO] com.corp.nodes:myproj-cli:myproj:1.0.0-SNAPSHOT
[INFO] \- com.corp.:myproj-model-impl:myproj:1.0.0-SNAPSHOT:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

Here I would have expected that I see a tree with three levels for each of the projects.

Here's the components.xml defined in my custom plugin:

<component-set>
    <components>
        <component>
            <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
            <role-hint>myproj</role-hint>
            <implementation>
                org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping
            </implementation>
            <configuration>
                <phases>
                    <initialize>com.corp.maven:myproj-plugin:unpackageDependencies</initialize>
                    <process-resources>org.apache.maven.plugins:maven-resources-plugin:resources</process-resources>
                    <compile>com.corp.maven:myproj-plugin:compile</compile>
                    <process-test-resources>org.apache.maven.plugins:maven-resources-plugin:testResources</process-test-resources>
                    <test-compile>org.apache.maven.plugins:maven-compiler-plugin:testCompile</test-compile>
                    <test>org.apache.maven.plugins:maven-surefire-plugin:test</test>
                    <package>com.corp.maven:myproj-plugin:package</package>
                    <install>org.apache.maven.plugins:maven-install-plugin:install</install>
                    <deploy>org.apache.maven.plugins:maven-deploy-plugin:deploy</deploy>
                </phases>
            </configuration>
        </component>
        <component>
            <role>org.apache.maven.artifact.handler.ArtifactHandler</role>
            <role-hint>myproj</role-hint>
            <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
            <configuration>
                <type>myproj</type>
                <extension>myproj</extension>
                <packaging>myproj</packaging>
                <addedToClasspath>true</addedToClasspath>
                <includesDependencies>true</includesDependencies>
            </configuration>
        </component>
    </components>
</component-set>

All of the project POMs have their packaging set to myproj, and all of the dependencies have their type set to myproj. Here's the pom for the cli project:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.corp.arthur.nodes</groupId>
    <artifactId>myproj-cli</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>myproj</packaging>

    <name>myproj Test</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.corp.arthur</groupId>
            <artifactId>myproj-model-impl</artifactId>
            <version>1.0.0-SNAPSHOT</version>
            <type>myproj</type>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>com.corp.maven</groupId>
                <artifactId>myproj-plugin</artifactId>
                <version>1.0.0-SNAPSHOT</version>
                <extensions>true</extensions>
            </plugin>
        </plugins>
    </build>
</project>

The POM for the impl project looks similar. Any idea's what I'm missing?

like image 234
Matt McMinn Avatar asked May 18 '18 19:05

Matt McMinn


People also ask

How do you exclude all transitive dependencies of a Maven dependency?

Exclude the transitive dependencyOpen the dependency POM and find the transitive dependency you want to exclude. Copy groupId and artifactId . In your project POM, underneath your active dependency, enter exclusions and using code completion paste the copied info of the dependency you want to exclude.

Does Maven support transitive dependencies?

Transitive Dependencies. Maven avoids the need to discover and specify the libraries that your own dependencies require by including transitive dependencies automatically. This feature is facilitated by reading the project files of your dependencies from the remote repositories specified.

Where can I find Maven transitive dependencies?

You can get this information in the Maven Tool Window. First go to View → Tool Windows → Maven, to make sure that the Maven window is visible. The top-level elements in the tree are your direct dependencies, and the child elements are the transitive dependencies.

How can you exclude a transitive dependency from downloading it?

Multiple transitive dependencies can be excluded by using the <exclusion> tag for each of the dependency you want to exclude and placing all these exclusion tags inside the <exclusions> tag in pom. xml.


1 Answers

Finally figured out what was going on by tracing through the source for the DefaultDependencyCollector class. Turns out I needed to set includesDependencies in my components.xml to false. What was happening is the dependency collector saw that flag was true, meaning the dependencies were included in the artifact, and so didn't recurse through them. With it set to false, it does recurse, and I get the expected behavior.

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------< com.corp.nodes:myproj-cli >------------------
[INFO] Building myproj Test: CLI Node 1.0.0-SNAPSHOT
[INFO] --------------------------------[ myproj ]--------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ myproj-cli ---
[INFO] com.corp.nodes:myproj-cli:myproj:1.0.0-SNAPSHOT
[INFO] \- com.corp:myproj-model-impl:myproj:1.0.0-SNAPSHOT:compile
[INFO]    \- com.corp:myproj-model:myproj:1.0.0-SNAPSHOT:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
like image 114
Matt McMinn Avatar answered Sep 27 '22 18:09

Matt McMinn