Maven doesn't recognize sibling modules when running mvn dependency:tree

Viewed 46710

I'm trying to set up a multi-module Maven project, and the inter-module dependencies are apparently not being set up correctly.

I have:

<modules>
  <module>commons</module>
  <module>storage</module>
</modules>

in the parent POM (which has a packaging-type pom) and then subdirectories commons/ and storage/ which define JAR poms with the same name.

Storage depends on Commons.

In the main (master) directory, I run mvn dependency:tree and see:

[INFO] Building system
[INFO]    task-segment: [dependency:tree]
[INFO] ------------------------------------------------------------------------
[INFO] [dependency:tree {execution: default-cli}]
[INFO] domain:system:pom:1.0-SNAPSHOT
[INFO] \- junit:junit:jar:3.8.1:test
[INFO] ------------------------------------------------------------------------
[INFO] Building commons
[INFO]    task-segment: [dependency:tree]
[INFO] ------------------------------------------------------------------------
[INFO] [dependency:tree {execution: default-cli}]
...correct tree...
[INFO] ------------------------------------------------------------------------
[INFO] Building storage
[INFO]    task-segment: [dependency:tree]
[INFO] ------------------------------------------------------------------------
Downloading: http://my.repo/artifactory/repo/domain/commons/1.0-SNAPSHOT/commons-1.0-SNAPSHOT.jar
[INFO] Unable to find resource 'domain:commons:jar:1.0-SNAPSHOT' in repository my.repo (http://my.repo/artifactory/repo)
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Failed to resolve artifact.

Missing:
----------
1) domain:commons:jar:1.0-SNAPSHOT

Why does the dependency on "commons" fail, even though the reactor has obviously seen it because it successfully processes its dependency tree? It should definitely not be going to the 'net to find it as it's right there...

The pom for storage:

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <packaging>jar</packaging>
  <parent>
    <artifactId>system</artifactId>
    <groupId>domain</groupId>
    <version>1.0-SNAPSHOT</version>
  </parent>
  <groupId>domain</groupId>
  <artifactId>storage</artifactId>
  <name>storage</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <!-- module dependencies -->
    <dependency>
      <groupId>domain</groupId>
      <artifactId>commons</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>

    <!-- other dependencies -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Thanks for any suggestions!

(Edit)

To clarify, what I am looking for here is this: I don't want to have to install module X to build module Y which depends on X, given that both are modules referenced from the same parent POM. This makes intuitive sense to me that if I have two things in the same source tree, I shouldn't have to install intermediate products to continue the build. Hopefully my thinking makes some sense here...

9 Answers

As discussed in this maven mailing list thread, the dependency:tree goal by itself will look things up in the repository rather than the reactor. You can work around this by mvn installing, as previously suggested, or doing something less onerous that invokes the reactor, such as

mvn compile dependency:tree

Works for me.

Bonusing off the answer from Don Willis:

If your build creates test-jars to share test code among your reactor submodules you should use:

mvn test-compile dependency:tree

which will allow dependency:tree to run to completion in this case.

In a Maven module structure like this:

- parent
  - child1
  - child2

You will have in the parent pom this:

<modules>
  <module>child1</module>
  <module>child2</module>
</modules>

If you now depend on child1 in child2 by putting the following in your <dependencies> in child2:

<dependency>
  <groupId>example</groupId>
  <artifactId>child1</artifactId>
</dependency>

You will receive an error that the JAR for child1 cannot be found. This can be solved by declaring a <dependencyManagement> block including child1 in the pom for parent:

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>example</groupId>
      <artifactId>child1</artifactId>
      <version>${project.version}</version>
    </dependency>
  </dependencies>
</dependencyManagement>

child1 will now be build when you run a compile or package etc. goal on parent, and child2 will find child1's compiled files.

Using version >= 3.1.2 of the dependency plugin seems to solve the issue.

Related