109

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...

André Gasser
  • 1,065
  • 2
  • 14
  • 34
Steven Schlansker
  • 37,580
  • 14
  • 81
  • 100
  • 2
    Ahhh, The edit is perfect. Why didn't you write this in the first intention? Also, maybe consider changing the title :) I don't mean to be picky, this is just for the sake of clarity and classification. This will help the whole community in the future when searching for a similar issue (which is not crystal clear with the actual title and content that is about dependency:tree) – Pascal Thivent Nov 05 '09 at 10:49
  • 1
    Hi. Did you find the solution? I have this problem too :( –  Oct 15 '10 at 03:08
  • 1
    Does compilation fail, or just the dependency:tree goal alone? See Don Willis' answer. – metamatt Mar 02 '11 at 00:18
  • OMG so in one module if it fails because it cannot find symbols of another module, the other should be added as dependency and installed as JAR? This is the key.... – WesternGun Sep 12 '17 at 15:35
  • it's sad maven 3.6 does not solve this problem yet – yuxh Nov 19 '18 at 11:28

9 Answers9

125

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.

Beryllium
  • 12,808
  • 10
  • 56
  • 86
Don Willis
  • 1,340
  • 2
  • 7
  • 7
  • 3
    Thank you for that cheap workaround. But is it a bug? I expect dependency:tree goal relies on the reactor without any trick. – mcoolive Jul 03 '15 at 16:31
  • It should be noted the same situation happens for any task that is run globally, but only affects some subprojects. – tkruse Apr 04 '17 at 07:10
  • Unfortunately, `compile` triggers the download of transitive dependencies. Is there also a way to list the dependency tree without actually downloading them (except the POMs, of course)? – sschuberth Apr 17 '17 at 12:47
  • I had the same problem for other goals. Adding `compile` (`validate` is not enough) helped there too: `mvn compile animal-sniffer:check` and `mvn compile org.basepom.maven:duplicate-finder-maven-plugin:check` – msa Mar 22 '19 at 07:35
  • Depending on your build, some Modules might also have dependencies to artifacts that are built in later phases. In my case a ZIP file (using maven-assembly-plugin) was built in `package` phase, so I needed to do e.g. `mvn package animal-sniffer:check`. – msa Mar 22 '19 at 07:46
23

I think the problem is that when you specify a dependency Maven expects to have it as jar (or whatever) packaged and available from at least a local repo. I'm sure that if you run mvn install on your commons project first everything will work.

Bostone
  • 36,858
  • 39
  • 167
  • 227
  • 4
    Is there a way to specify that I want it to use whatever version of the module is in the source tree? I thought that this case would be handled automatically. I don't want / don't think Maven requires to have to build-install-build-install-build every time I just want to make the entire project! – Steven Schlansker Nov 05 '09 at 01:09
  • 43
    You're correct that running install fixes it. However, now I have to install every time I make changes, which isn't what I want. I want the storage project to pick up the latest code from the commons project. – Steven Schlansker Nov 05 '09 at 01:15
  • I actually have to deal with similar issues and alas - I'm not able to find answer so far. It looks like Maven doesn't care that dependency is linked to your module it just goes to repo right away. I'll put favorite on your question - so maybe some guru will respond. I'm interested to find out if this can be done – Bostone Nov 05 '09 at 01:22
  • @Steven Please post your concern as another question, it's not handy to answer in a comment and this is another subject. – Pascal Thivent Nov 05 '09 at 02:43
  • 6
    That was intended to be the main question, I was simply clarifying. Did I not make it clear in the original question that my intent is to not require built products to be in the local repository to build other modules in the same project? – Steven Schlansker Nov 05 '09 at 07:00
  • For me (plugin version 2.10) it does not help if I do "install dependency:tree" instead of just "dependency:tree"... – Egon Willighagen Dec 24 '15 at 06:54
  • 1
    (years later for Google completeness) The correct answer is to add pom to the dependency as explained by bsautner – earizon Sep 15 '17 at 10:06
  • Since https://issues.apache.org/jira/browse/MDEP-409 fix, dependency:tree works without requiring a previous install execution. – Réda Housni Alaoui Feb 23 '19 at 14:29
10

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.

adrock20
  • 175
  • 1
  • 7
8

Realizing this is an older thread but it seems that either the tool evolved or this might have been missed the first time around.

It is possible to perform a build that makes dependencies resolved without installing by doing a reactor build.

If you start your build in the parent that describes the module structure of your project then your dependencies between your modules will be resolved during the build itself through the internal Maven reactor.

Of course this is not the perfect solution since it does not solve the build of a single individual module within the structure. In this case Maven will not have the dependencies in his reactor and will bee looking to resolve it in the repository. So for individual builds you still have to install the dependencies first.

Here is some reference describing this situation.

Newtopian
  • 7,543
  • 4
  • 48
  • 71
  • 1
    Is there any way to build a single module, without installing the dependencies first and without building the complete parent project? – Has QUIT--Anony-Mousse Apr 01 '13 at 16:40
  • 2
    To complete the answer - if plugin is invoked directly (without phases) e.g. `mvn dependency:tree`, it still won't resolve the dependencies from sources unless you invoke `compile` phase. So this would work instead: `mvn compile dependency:tree`. – Stanislav Bashkyrtsev Oct 16 '16 at 21:39
5

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.

bothor
  • 59
  • 1
  • 1
  • 1
    Thanks. It really works for me. Nevertheless, why does the Jetty project work well without the `dependencyManagement` tag in the child modules? For example, the _jetty-io_ module reference _jetty-util_. ``` org.eclipse.jetty jetty-util ${project.version} ``` – Kellen Nov 10 '22 at 08:26
4

for me, what led me to this thread was a similar problem and the solution was to ensure all module dependency pom's had

 <packaging>pom</packaging>

the parent had

pom

my model dep had pom - so there was no jar to be found.

bsautner
  • 4,479
  • 1
  • 36
  • 50
3

The only thing that workd for me : switching to gradle :(

I have

Parent
  +---dep1
  +---war1 (using dep1)

and I can just cd in war1 and use mvn tomcat7:run-war. I always have to install the whole project before, despite war1 references his parent and the parent references war1 and dep1 (as modules) so all dependencies should be known.

I don't understand what the problem is.

mba
  • 429
  • 6
  • 10
2

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

sergeko
  • 21
  • 1
0

Make sure the module which is failing gets resolved in the pom, is pointing to the right parent by including the configurations in the pom file of the module.

Nitin Kamate
  • 2,545
  • 1
  • 18
  • 13