Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maven and dependent modules

Colleagues have been touting the wonders of maven and its magical dependency stuff but I'm finding that it fails at what I would consider the obvious use.

Suppose I have a root folder with a master POM.

Then underneath I have some projects, call them A and B

B requires A and so the POM in the B folder has the appropriate dependency entry in it

Now, back in the root folder, in a profile, I specify that I want to build B.

When I perform the usual mvn clean install, I get a failure because A was not built.

My friends tell me I have to specify both A and B in that main profile in the root.

But isn't the whole point of dependency management that maven sees B, goes to the B POM file where it sees the dependency on A and so it should go build A automatically.

like image 909
David Avatar asked Apr 30 '09 18:04

David


People also ask

Can two Maven modules depend on each other?

Because modules within a multi-module build can depend on each other, it is important that the reactor sorts all the projects in a way that guarantees any project is built before it is required. The following relationships are honoured when sorting projects: a project dependency on another module in the build.

What is Maven and its dependency?

What is Maven Dependency? In Maven, a dependency is just another archive—JAR, ZIP, and so on—which our current project needs in order to compile, build, test, and/or run. These project dependencies are collectively specified in the pom. xml file, inside of a <dependencies> tag.

What are Maven modules?

A Maven module is a sub-project. To create a Maven module you will need to already have a Maven project available. The parent project must have its Packaging option pre-configured to pom, for a module to be created and associated with it.

What is the difference between Maven module and Maven project?

a maven module is like a maven "sub-project". a maven project includes 1 or more modules. more info here. Typically, a module generates a single artifact (jar, war, zip, etc), although this is not always true.


2 Answers

With the master POM:

~/scratch/pom.xml

<?xml version="1.0" encoding="UTF-8"?> <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>scratch</groupId>     <artifactId>scratch</artifactId>     <packaging>pom</packaging>     <version>1.0-SNAPSHOT</version>      <modules>         <module>nipple</module>         <module>cabbage</module>     </modules> </project> 

And the module POMs:

~/scratch/nipple/pom.xml

<?xml version="1.0" encoding="UTF-8"?> <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">      <parent>         <artifactId>scratch</artifactId>         <groupId>scratch</groupId>         <version>1.0-SNAPSHOT</version>     </parent>      <modelVersion>4.0.0</modelVersion>      <groupId>scratch</groupId>     <artifactId>nipple</artifactId>     <version>1.0-SNAPSHOT</version>  </project> 

~/scratch/cabbage/pom.xml

<?xml version="1.0" encoding="UTF-8"?> <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">      <parent>         <artifactId>scratch</artifactId>         <groupId>scratch</groupId>         <version>1.0-SNAPSHOT</version>     </parent>      <modelVersion>4.0.0</modelVersion>      <groupId>scratch</groupId>     <artifactId>cabbage</artifactId>     <version>1.0-SNAPSHOT</version>     <dependencies>         <dependency>             <groupId>scratch</groupId>             <artifactId>nipple</artifactId>             <version>1.0-SNAPSHOT</version>         </dependency>     </dependencies>  </project> 

I can issue mvn package in the root directory after clearing out my local repository and end up with all the modules built. (Into empty-ish JARs, but built.)

Maven seems to look for dependencies either in the repository, or in the build in progress. It will not automatically traverse your project structure when you're only building a single module, because it's not required that you even have the parent project on your computer, much less one directory above the current module. (The parent-child relationship isn't even bijective.)

A reason why this is so might be because a directory layout where the location of modules would be predictable is in no way mandatory. It's even somewhat common and acceptable that the layout for the above example be like this:

projects | +--scratch |  | |  +--scratch-parent |  |  | |  |  +--pom.xml [The POM of scratch:scratch:1.0-SNAPSHOT] |  | |  +--nipple |  |  | |  |  +--pom.xml [The POM of scratch:mod1:1.0-SNAPSHOT] |  | |  +--cabbage |  |  | |  |  +--pom.xml [The POM of scratch:mod2:1.0-SNAPSHOT] 

In this case, the <modules> section of the parent POM would be:

<modules>     <module>../nipple</module>     <module>../cabbage</module> </modules> 

Notice that there is nothing saying which artifact ID is in which module. It just serves to tell Maven that these are filesystem locations where to search for other artifacts related to this build.

like image 151
millimoose Avatar answered Oct 22 '22 17:10

millimoose


A reason I can think of that your desired behaviour hasn't been implemented is as follows:

Suppose I'm working on both projects A and B. Currently A is broken. If dependency resolution happened as you would like, I would never be able to build B until A was fixed. So I either have to roll back my changes to A, or focus on fixing A first. Either way possibly not what I want to focus on right now.

Generally B wants to work with the "last good" version of A, rather than the latest. Using the dependencies from the repository means they at least compiled ok (and hopefully the unit tests were run too).

like image 34
Rich Seller Avatar answered Oct 22 '22 17:10

Rich Seller