Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maven reactor builds in order that doesn't satisfy all dependencies

Tags:

maven

maven-3

I am having trouble with build ordering in a SNAPSHOT build using Maven. The reactor is building all of the jars in an invalid order.

The following is an example structure to recreate the issue (the project I'm having issues with is much larger, >100 jars):

pom.xml        [reactor]
parent/pom.xml [parent]
jar1/pom.xml
jar2/pom.xml
jar3/pom.xml

pom.xml [reactor]

<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>
  <packaging>pom</packaging>
  <groupId>com.test.buildorder</groupId>
  <artifactId>reactor</artifactId>
  <version>1.0</version>
  <modules>
    <module>jar3</module>
    <module>jar2</module>
    <module>jar1</module>
  </modules>
</project>

parent/pom.xml

<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.test.buildorder</groupId>
  <artifactId>parent</artifactId>
  <version>1.1</version>
  <packaging>pom</packaging>

  <dependencyManagement>
  <dependencies>
      <dependency>
        <groupId>com.test.buildorder</groupId>
        <artifactId>jar1</artifactId>
        <version>1.1</version>
      </dependency>
      <dependency>
        <groupId>com.test.buildorder</groupId>
        <artifactId>jar2</artifactId>
        <version>1.0</version>
      </dependency>
      <dependency>
        <groupId>com.test.buildorder</groupId>
        <artifactId>jar3</artifactId>
        <version>1.1</version>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>

jar1/pom.xml

<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.test.buildorder</groupId>
  <artifactId>jar1</artifactId>
  <version>1.1</version>
  <parent>
    <groupId>com.test.buildorder</groupId>
    <artifactId>parent</artifactId>
    <version>1.1</version>
  </parent>
</project>

jar2/pom.xml

<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.test.buildorder</groupId>
  <artifactId>jar2</artifactId>
  <version>1.1</version>
  <parent>
    <groupId>com.test.buildorder</groupId>
    <artifactId>parent</artifactId>
    <version>1.0</version>
  </parent>

  <dependencies>
    <dependency>
      <groupId>com.test.buildorder</groupId>
      <artifactId>jar1</artifactId>
    </dependency>
  </dependencies>
</project>

jar3/pom.xml

<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.test.buildorder</groupId>
  <artifactId>jar3</artifactId>
  <version>1.1</version>
  <parent>
    <groupId>com.test.buildorder</groupId>
    <artifactId>parent</artifactId>
    <version>1.1</version>
  </parent>

  <dependencies>
    <dependency>
      <groupId>com.test.buildorder</groupId>
      <artifactId>jar2</artifactId>
    </dependency>
  </dependencies>
</project>

My repository (local in this case) only has the released 1.0 versions of each jar and jar3-1.0 depended on jar2-1.0, and jar2-1.0 depended on jar1-1.0 and each had parent-1.0 (I can post this code if needed, but my question is already really long so I'll hold off unless asked).

I now install the 1.1 parent pom above, and then attempt to run an install on the reactor and get the following result.

[INFO] Scanning for projects...
[WARNING]
[WARNING] Some problems were encountered while building the effective model for com.test.buildorder:jar3:jar:1.1
[WARNING] 'parent.relativePath' points at com.test.buildorder:reactor instead of com.test.buildorder:parent, please verify your project structure @ line 6, column 11
[WARNING]
[WARNING] Some problems were encountered while building the effective model for com.test.buildorder:jar2:jar:1.1
[WARNING] 'parent.relativePath' points at com.test.buildorder:reactor instead of com.test.buildorder:parent, please verify your project structure @ line 6, column 11
[WARNING]
[WARNING] Some problems were encountered while building the effective model for com.test.buildorder:jar1:jar:1.1
[WARNING] 'parent.relativePath' points at com.test.buildorder:reactor instead of com.test.buildorder:parent, please verify your project structure @ line 6, column 11
[WARNING]
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
[WARNING]
[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
[WARNING]
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] jar3
[INFO] jar2
[INFO] jar1
[INFO] reactor
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building jar3 1.1
[INFO] ------------------------------------------------------------------------
Downloading: https://repo.maven.apache.org/maven2/com/test/buildorder/jar1/1.1/jar1-1.1.jar
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] jar3 ............................................... FAILURE [  0.645 s]
[INFO] jar2 ............................................... SKIPPED
[INFO] jar1 ............................................... SKIPPED
[INFO] reactor ............................................ SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.775 s
[INFO] Finished at: 2015-06-03T16:56:04-05:00
[INFO] Final Memory: 4M/15M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal on project jar3: Could not resolve dependencies for project com.test.buildorder:jar3:jar:1.1: Could not find artifact com.test.buildorder:jar1:jar:1.1 in central (https://repo.maven.apache.org/maven2) -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/DependencyResolutionException

When I built the 1.0 versions the Reactor was smart enough to realize the dependency tree jar3-1.0 -> jar2-1.0 -> jar1-1.0 and build in the order jar1, jar2, jar3 to satisfy the dependencies.

Now though because jar3-1.1 depends on jar2-1.0 (which is in the repo) the reactor does not assume that jar1 needs to be built first but the debug (using the -X argument) shows the dependency tree to be:

[DEBUG] com.test.buildorder:jar3:jar:1.1
[DEBUG]    com.test.buildorder:jar2:jar:1.0:compile
[DEBUG]       com.test.buildorder:jar1:jar:1.1:compile (version managed from 1.0 by com.test.buildorder:parent:1.1)

So I have a few questions about this scenario:
1. Why does maven think jar3-1.1 has a transitive dependency to jar1-1.1?
2. Why does the reactor not realize this transitive dependency and build in the required order to satisfy it?
3. What can I do to prevent this issue from occurring? (Preferrably without rewriting over 100 poms.)

Edit: found answer to question one, and one solution to question three. But still would like to hear about question two.

1. Because I never defined a scope to the dependencies maven determines assigned a default scope of compile. Because of this the dependency from jar2 to jar1 will appear as a transitive dependency for jars that depend on jar2 (such as jar3). (version managed from 1.0 by com.test.buildorder:parent:1.1) informs me that the dependency is from jar2-1.0 to jar1-1.0 but because the parent specifies another version for jar 1 (1.1) it takes that.

3. If I change the scope of the dependency from jar2 to jar1 to provided the dependency no longer becomes transitive. This assumes that at runtime the required jars will all be present, so this may not be the solution for everybody who comes across this issue. Here is a guide to the scopes available in Maven

like image 991
Ben A Avatar asked Jun 03 '15 22:06

Ben A


2 Answers

I installed all your projects with all versions set to 1.0 here. Then I changed the versions as you stated and got the same error.

After changing the reactor POM to:

 <modules>
    <module>jar1</module>
    <module>jar2</module>
    <module>jar3</module>
</modules>

... the build succeeded.

I looked at Guide to Working with Multiple Modules, Reactor Sorting and the last option there is:

  • the order declared in the <modules> element (if no other rule applies)

After reading the next sentence:

Note that only "instantiated" references are used - dependencyManagement and pluginManagement elements will not cause a change to the reactor sort order

  • I restored the reactor POM
  • I commented the <dependencyManagement> section in the parent POM and added <version> to the jar2 and jar3 POMs explicitly

and the build succeeded with:

[INFO] Reactor Build Order
[INFO]
[INFO] jar3
[INFO] jar1
[INFO] jar2
[INFO] reactor
like image 51
Gerold Broser Avatar answered Oct 16 '22 17:10

Gerold Broser


[WARNING] Some problems were encountered while building the effective model for com.test.buildorder:jar3:jar:1.1 [WARNING] 'parent.relativePath' points at com.test.buildorder:reactor instead of com.test.buildorder:parent,

Since your reactor isn't the parent I assume you need to define the relative path explicitly

<parent>
    <groupId>com.test.buildorder</groupId>
    <artifactId>parent</artifactId>
    <version>1.1</version>
    <relativePath>../parent</relativePath>
  </parent>

Additionally you have a different versions of the jar2 1.0 and 1.1. align them

like image 1
Yuri G. Avatar answered Oct 16 '22 18:10

Yuri G.