views:

720

answers:

3

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"&gt;
  <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&lt;/url&gt;
  <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...

A: 

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.

DroidIn.net
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
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
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
DroidIn.net
@Steven Please post your concern as another question, it's not handy to answer in a comment and this is another subject.
Pascal Thivent
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
+1  A: 

Has anybody solved this problem yet? "Just run install" is not a valid solution. As soon as you try to do a release build, the release plugin will not do this for the release:perform goal which will in fact fail.

Jonothan Farr
In this case, however, you have a parent project. You should be releasing based upon the parent, and not the sub-projects. At least that's what I have done.
Mike Cornell
+2  A: 

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.

Don Willis