I'm having a hard time setting up a set of related maven projects with interdependencies between them.
Here's my simplified case:
pom.xml -- parent pom \base\ pom.xml src\main\java\Base.java -- this is just a simple class \derived\ pom.xml src\main\java\Derived.java -- this is a simple class that needs Base class to compile successfully, and has a main function
My goals are:
mnv clean compile
is successful in \mnv clean compile
is successful in \base\ and \derived\ (though this may not work by design: Inter Project Dependencies in Maven) mvn clean compile install
instead of doing just doing mvn clean compile
. Once this is done, doing mvn clean compile
in \derived works fine. Still, it would be great to do this without touching global state, i.e. without having to install base -- so if anyone knows a way of achieving this, please add it as an answer] mvn exec:run
in \derived\ should compile (if needed) and run the derived.jarmvn clean compile ???
will push this to the shared repository specified in ~/.m2/config.xmlmvn clean compile ???
will push derived.jar and dependencies (like base.jar) to ~/.m2/maven.repo/.../derived or equivalent, and then I can cd ~/.m2/maven.repo/.../derived and run java -jar derived.jar
to run it.mvn clean compile ???
will push base.jar to ~/.m2/maven.repo/.../base (or derived.jar to its corresponding dir), which is already exposed as a download point via local web or ftp server.How do I do the goals above?
Here's the relevant section from parent pom:
... <modelVersion>4.0.0</modelVersion> <groupId>com.foo</groupId> <artifactId>parentpom</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <name>parentpom</name> <modules> <module>base</module> <module>derived</module> </modules> ...
Here's the relevant section from base pom.xml:
... <parent> <groupId>com.foo</groupId> <artifactId>parentpom</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <groupId>com.foo.base</groupId> <artifactId>base</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>base</name> ...
Here's the relevant section from derived pom.xml:
... <parent> <groupId>com.foo</groupId> <artifactId>parentpom</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <groupId>com.foo.derived</groupId> <artifactId>derived</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>derived</name> <dependencies> <dependency> <groupId>com.foo</groupId> <artifactId>base</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> ...
Thank you in advance for your help.
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.
Right-click the utility project, and select Maven>Add Dependency. Type a dependency name in the Enter groupID… field (e.g., commons-logging) to search for a dependency. Select the dependency, and click OK.
let's assume that you have two maven projects A and B. Now create a new project C in your intllij-idea. In project C, create a new module A1. Copy the dependencies and build, properties (if present) from pom.
POM Aggregator (Parent POM) Let's understand the structure of the multi-module application that we have created. Step 1: Create a Maven Project with the name spring-boot-multimodule. Step 2: Open the pom. xml (parent pom) file and change the packaging type jar to pom.
Your parent pom looks good but your module/derived poms don't: There are several issues which will produce some problems etc.
First you are using different groupId's for the derived/base module. If you have a multi-module build you shouldn't do this. Furthermore, the version of derived/base is inherited by the parent and shouldn't be set explicit which means you should have something like the following:
<modelVersion>...</...> ... <parent> <groupId>com.foo</groupId> <artifactId>parentpom</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>base</artifactId> <packaging>jar</packaging> <name>base</name>
The groupId is usually inherited. But sometimes you have a larger number of modules that may be sub-modules of sub-modules which results in a structure like this:
+--- parent (pom.xml) +--- mod1 (pom.xml) +--- mod11 (pom.xml) +--- mod12 (pom.xml) +--- mod2 (pom.xml)
In Such cases, the mod1 itself is a a pom packaging module:
<modelVersion>...</...> ... <groupId>com.company.project<groupId> <artifactId>parent</artifactId> <packaging>pom</packaging> <modules> <module>mod1</module> <module>mod2</module> </modules>
mod1:
<parent> <groupId>com.company.project<groupId> <artifactId>parent</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <groupId>com.company.project.mod1</groupId> <artifactId>mod1</artifactId> <packaging>pom</packaging> <modules> <module>mod11</module> <module>mod12</module> </modules>
mod11:
<parent> <groupId>com.company.project.mod1</groupId> <artifactId>mod1</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>mod11</artifactId> <packaging>pom</packaging> <modules> <module>mod11</module> <module>mod12</module> </modules>
If you need to make a dependency between modules the solution is:
<parent> <groupId>com.company.project.mod1</groupId> <artifactId>mod1</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>mod11</artifactId> <packaging>jar</packaging> <dependencies> <dependency> <!-- This shouldn't be a dep which is packaging: pom --> <groupId>${project.groupId}</groupId> <artifactId>mod2</artifactId> <version>${project.version}</version> </dependency> </dependencies>
To compile the whole project with all sub modules in one just go to parent folder and:
mvn clean package
will compile etc. If you like to compile only a single project you can do this by (from parent):
mvn -pl mod1
which will work only if you have installed the whole project once before. Another solution is:
mvn -am -pl mod1
To make the artifacts acessible for others the simplest solution is to install a repository manager and do:
mvn deploy
All others can use and artifact as a SNAPSHOT dependency.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With