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