Why are duplicate dependencies in dependencyManagement not inherited? - maven

If I add a duplicate dependency in dependencyManagement, which is already managed in parent pom, dependency management only considers this last declaration, anything declared in parent is ignored.
Are there any use-cases not inherit parent dependencyManagement?
In my hypothetical example I have org.jooq:jooq:3.16.9 which depends on io.r2dbc:r2dbc-spi:0.9.0.RELEASE.
Parent POM declares a newer version io.r2dbc:r2dbc-spi:0.9.1.RELEASE. If Child POMs would use jooq they would get 0.9.1.RELEASE of io.r2dbc:r2dbc-spi. This is an expected behavior. So far so good.
If now a Child POM decides to change only the scope and does not provide a version, Maven resolves the version of io.r2dbc:r2dbc-spi to 0.9.0.RELEASE, which is declared by org.jooq:jooq:3.16.9.
(Same behavior with scope and exclusions, even when I import parent instead of inheriting.)
I expected, that Maven would resolve io.r2dbc:r2dbc-spi to 0.9.1.RELEASE since it is declared in parent dependencyManagement.
Duplicate dependencies in dependencyManagement are re-declared and not inherited:
Finally, since d is specified in B's dependency management section, should d be a dependency (or transitive dependency) of a or c, version 1.0 will be chosen - again because dependency management takes precedence over dependency mediation and also because the current POM's declaration takes precedence over its parent's declaration.
POMs
(Actual artifacts are only used for illustration purpose, there might have been other better artifacts ...)
Parent POM:
<?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>org.example</groupId>
<artifactId>MavenParentTest</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.r2dbc</groupId>
<artifactId>r2dbc-spi</artifactId>
<version>0.9.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.jooq</groupId>
<artifactId>jooq</artifactId>
<version>3.16.9</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.3.0</version> <!-- just to fix plugins version -->
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
Child POM:
<?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>
<artifactId>MavenChildTest</artifactId>
<parent>
<groupId>org.example</groupId>
<artifactId>MavenParentTest</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.r2dbc</groupId>
<artifactId>r2dbc-spi</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jooq</groupId>
<artifactId>jooq</artifactId>
</dependency>
</dependencies>
</project>
Running: mvn dependency:tree -f child/pom.xml leads to following output:
[INFO] --- maven-dependency-plugin:3.3.0:tree (default-cli) # MavenChildTest ---
[INFO] org.example:MavenChildTest:jar:1.0-SNAPSHOT
[INFO] \- org.jooq:jooq:jar:3.16.9:compile
[INFO] +- io.r2dbc:r2dbc-spi:jar:0.9.0.RELEASE:runtime
[INFO] | \- org.reactivestreams:reactive-streams:jar:1.0.3:runtime
[INFO] \- jakarta.xml.bind:jakarta.xml.bind-api:jar:3.0.0:compile
[INFO] \- com.sun.activation:jakarta.activation:jar:2.0.0:compile

Related

Are maven's profile-specific dependencies propagated to the published artifact?

I need to publish an artifact twice - each with a different set of dependencies. I'm happy to give the artifacts different ids but would like to use the same pom.xml file. I've attempted this with profile-specific dependencies, but I can't seem to get these dependencies visible as transitive dependencies in the artifacts. Is that possible?
pom1.xml - creates profile-specific builds. The A profile adds a dependency on commons-collections 3.2.2 and profile B depends on 3.2.1.
pom2.xml - simply defines a dependency on pom1's artifact.
src/main/java/tt.java - defines an empty class to provide something to compile by pom1.
mvn version is 3.8.5.
% mvn -f pom1.xml -P A dependency:tree
...
[INFO] org.acme:testing:jar:testing
[INFO] \- commons-collections:commons-collections:jar:3.2.2:compile
...
% mvn -f pom1.xml -P B dependency:tree
...
[INFO] org.acme:testing:jar:testing
[INFO] \- commons-collections:commons-collections:jar:3.2.1:compile
...
% mvn -f pom1.xml -P A clean install
...
% mvn -f pom2.xml dependency:tree
...
[INFO] org.acme:testing2:jar:testing
[INFO] \- org.acme:testing:jar:testing:compile
[INFO] \- commons-collections:commons-collections:jar:3.2.1:compile
It seems to me pom2's dependencies should have been on 3.2.2 from profile A.
Any idea on how I might make the dependencies from profile A transitive to dependent poms?
pom1.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>org.acme</groupId>
<artifactId>testing</artifactId>
<version>testing</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>A</id>
<properties>
<profile.name>cuda11.2</profile.name>
</properties>
<dependencies>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.2</version>
</dependency>
</dependencies>
</profile>
<profile>
<id>B</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<profile.name>cpu</profile.name>
</properties>
<dependencies>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
</dependencies>
</profile>
</profiles>
<!-- If I move this dependency out of the profile, then it becomes visible
as a transitive depenency to other projects referencing this pom's artifact.
<dependencies>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.2</version>
</dependency>
</dependencies>
-->
</project>
pom2.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>org.acme</groupId>
<artifactId>testing2</artifactId>
<version>testing</version>
<dependencies>
<dependency>
<groupId>org.acme</groupId>
<artifactId>testing</artifactId>
<version>testing</version>
</dependency>
</dependencies>
</project>

why the version of library in my project is different from it's parent pom declaration?

I simplify my project structure and find some clues. My project structure looks like the following:
-------- project 1 ---------
parent
|_ project-a
|_ src
|_ pom.xml
|_ pom.xml
------- project 2 ----------
project-b
|_ src
|_ pom.xml
---------------------------
In project 1, parent is maven parent for project-a, it's pom.xml looks like this:
<?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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- spring boot parent -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/>
</parent>
<groupId>com.demo</groupId>
<artifactId>parent</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<name>A custom project using myfaces</name>
<url>http://www.myorganization.org</url>
<modules>
<module>project-a</module>
</modules>
<dependencies>
</dependencies>
</project>
In parent's pom, it declares spring boot as it's maven parent and project-a as it's module. In project-a, it's pom is as follows:
<?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>parent</artifactId>
<groupId>com.demo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>project-a</artifactId>
<packaging>jar</packaging>
<name>project-a Maven Webapp</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<testSource>1.8</testSource>
<testTarget>1.8</testTarget>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
project-b is a standalone project, it's pom looks like the following:
<?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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- parent declaration is the key point of this problem! -->
<parent>
<artifactId>parent</artifactId>
<groupId>com.demo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.demo</groupId>
<artifactId>project-b</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>A custom project using myfaces</name>
<url>http://www.myorganization.org</url>
<!-- Project dependencies -->
<dependencies>
<dependency>
<groupId>com.demo</groupId>
<artifactId>project-a</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
<classifier>exec</classifier>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
</plugins>
</build>
</project>
After installing project 1 by mvn install, the dependency tree of project-b is as follows:
[INFO] --- maven-dependency-plugin:3.1.1:tree (default-cli) # project-b ---
[INFO] com.demo:project-b:jar:1.0-SNAPSHOT
[INFO] \- com.demo:project-a:jar:1.0-SNAPSHOT:compile
[INFO] \- mysql:mysql-connector-java:jar:8.0.16:runtime
But if I remove the parent declaration in project-b's pom, the dependency tree of project-b is what I expected:
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) # project-b ---
[INFO] com.demo:project-b:jar:1.0-SNAPSHOT
[INFO] \- com.demo:project-a:jar:1.0-SNAPSHOT:compile
[INFO] \- mysql:mysql-connector-java:jar:8.0.11:runtime
I also have tried to remove the parent dependency of spring boot in project 1 parent's pom, after reinstalling project 1, and the result is what I expected too. so I guess the parent declaration is the key point, but why?
Best Regards.
This is because parent's dependency has more higher priority than project-a's one.
You can refer to this document.
https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
  Dependency mediation - this determines what version of an artifact will be chosen when multiple versions are encountered as dependencies. Maven picks the "nearest definition". That is, it uses the version of the closest dependency to your project in the tree of dependencies. You can always guarantee a version by declaring it explicitly in your project's POM. Note that if two dependency versions are at the same depth in the dependency tree, the first declaration wins.
  "nearest definition" means that the version used will be the closest one to your project in the tree of dependencies. For example, if dependencies for A, B, and C are defined as A -> B -> C -> D 2.0 and A -> E -> D 1.0, then D 1.0 will be used when building A because the path from A to D through E is shorter. You could explicitly add a dependency to D 2.0 in A to force the use of D 2.0.
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
Since this module also has a dependency of mysql-connector-java(8.0.16), maven use this instead of project-a's one.
https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-parent/2.1.6.RELEASE
project-b
parent
|----mysql-connector-java(8.0.16) <- maven choose this because its level is higher
|----project-a
|----mysql-connector-java(8.0.11)
Maybe like this..? (please let me know if I'm miss understood)

Compile project that references installed project

I have a library module that I created through Maven, there is pom.xml what get dependencies:
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.18.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example.library</groupId>
<artifactId>commons</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>commons</name>
<description>common dependencies library</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
With the above pom, I successfully installed it into the local maven repository by using mvn install.
In another project my-service, which uses this installed library, within the IntelliJ IDEA, it is fine compiling and running. There is the pom.xml for the my-service
<?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>com.example</groupId>
<artifactId>my-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>my-service</name>
<description>My Services</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.18.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- other dependencies ... -->
<dependency>
<groupId>com.example.library</groupId>
<artifactId>commons</artifactId>
<version>1.0.0</version>
</dependency>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
However, when running with mvn compile, I got the following errors:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project my-service: Compilation failure: Compilation failure:
[ERROR] /Users/doe/IdeaProjects/my-service/src/main/java/com/example/myservice/configs/WebSecurityConfig.java:[3,45] package com.example.library.commons.filters does not exist
[ERROR] /Users/doe/IdeaProjects/my-service/src/main/java/com/example/myservice/configs/WebSecurityConfig.java:[17,13] cannot find symbol
[ERROR] symbol: class SessionFilter
[ERROR] location: class com.example.myservice.configs.WebSecurityConfig
[ERROR] /Users/doe/IdeaProjects/my-service/src/main/java/com/example/myservice/configs/WebSecurityConfig.java:[19,36] cannot find symbol
[ERROR] symbol: class SessionFilter
[ERROR] location: class com.example.myservice.configs.WebSecurityConfig
The library project is created as part of the IntelliJ IDEA module within the same project as the my-service module. I guess the IntelliJ IDEA knows how to internally references module to compile the depending modules, but with Maven, it is a different story.
My goal is to compile and package the my-service module as a single jar that includes the commons library module. Now I can't even get it to compile with Maven, what did I do wrong?
Apache Maven version 3.3.9 . Operating system: OS X.
It turns out the Spring-boot-maven plugin is not needed in the library project because a library doesn't need to produce an executable ueber jar. After removing the plugin, it compiles successfully.

How does Maven handle transitive dependencies inherited from parent?

Given the parent and child pom below and lib1 and lib2 both include the class foo.bar.Test.
parent pom
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>foo</groupId>
<artifactId>foo-parent</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>my.transitive</groupId>
<artifactId>lib1</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</project>
child pom
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>foo</groupId>
<artifactId>foo-parent</artifactId>
<version>1.0</version>
</parent>
<artifactId>foo-child</artifactId>
<dependencies>
<dependency>
<groupId>my.transitive</groupId>
<artifactId>lib2</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</project>
If I include foo-child as a dependency in myApp and instantiate foo.bar.Test, which version of the class would Maven resolve to? And why?
my app pom
<project>
<modelVersion>4.0.0</modelVersion>
<artifactId>myApp</artifactId>
<groupId>myApp</groupId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>foo</groupId>
<artifactId>foo-child</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</project>
The short answer would be: it depends on which one is found on the classpath first.
Having 2 of the same classes packaged with an application is not ideal as it can lead to many difficult to debug errors... If your myApp project is just going to be a jar then it would be best to compile it using the same library as what is going to be available to it at runtime.
I believe maven uses the order it is written to the pom to build. One way of looking at this would be to run the following command for myApp:
mvn dependency:tree -Dverbose
This will print the dependencies in the order that they should appear on the classpath per spec. You can always use exclusions to exclude any inherited library you might not want. Hope this helps.

How to build an EAR project with EJB and WAR using Maven?

I tried to create EAR Project with EJB and WAR but I have some problem.
I created the main project from the Java EE 6 EAR Archetype:
<dependency>
<groupId>org.codehaus.mojo.archetypes</groupId>
<artifactId>ear-javaee6</artifactId>
<version>1.5</version>
</dependency>
Then I created the EJB module from the Java EE 6 EJB JAR Archetype:
<dependency>
<groupId>org.codehaus.mojo.archetypes</groupId>
<artifactId>ejb-javaee6</artifactId>
<version>1.5</version>
</dependency>
And then I created the second module from the Javax Faces WAR Archetype:
<dependency>
<groupId>javax.faces</groupId>
<artifactId>javax.faces-war-archetype</artifactId>
<version>2.2</version>
</dependency>
Then I added dependencies to main pom.xml:
<!-- Define the versions of your ear components here -->
<dependencies>
<dependency>
<groupId>QCforCC-main</groupId>
<artifactId>QCforCC-ejb</artifactId>
<version>1.0-SNAPSHOT</version>
<type>ejb</type>
</dependency>
<dependency>
<groupId>QCforCC-main</groupId>
<artifactId>QCforCC-war</artifactId>
<version>1.0-SNAPSHOT</version>
<type>war</type>
</dependency>
</dependencies>
And then I tried to build the project - using maven clean and instal .
But I have an error:
[ERROR] The projects in the reactor contain a cyclic reference: Edge between 'Vertex{label='QCforCC-main:QCforCC-war:1.0-SNAPSHOT'}' and 'Vertex{label='QCforCC-main:QCforCC-ejb:1.0-SNAPSHOT'}' introduces to cycle in the graph QCforCC-main:QCforCC-ejb:1.0-SNAPSHOT --> QCforCC-main:QCforCC-war:1.0-SNAPSHOT --> QCforCC-main:QCforCC-ejb:1.0-SNAPSHOT - [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/ProjectCycleException
Process finished with exit code 1
And in EAR pom.xml I have:
<modules>
<module>QCforCC-ejb</module>
<module>QCforCC-war</module>
</modules>
<packaging>pom</packaging>
But if I change <packaging>pom</packaging> to <packaging>ear</packaging>
IDEA show error in popup:
Some problems were encountered while processing the POMs:
[WARNING] 'build.plugins.plugin.(groupId:artifactId)' must be unique but found duplicate declaration of plugin org.apache.maven.plugins:maven-ear-plugin # line 41, column 21
[ERROR] 'packaging' with value 'ear' is invalid. Aggregator projects require 'pom' as packaging. # line 12, column 16
I highly suggest that you understand how multi-module builds work. The Sonatype book has a great chapter describing in great detail.
To build an EAR with an EJB and a WAR, you actually need three modules, for the EJB, WAR and EAR. The parent POM just holds everything together and has a packaging type of POM.
So the parent pom.xml should look like this:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.sonatype.mavenbook.multi</groupId>
<artifactId>simple-parent</artifactId>
<packaging>pom</packaging>
<version>1.0</version>
<name>Multi Chapter Simple Parent Project</name>
<modules>
<module>ejb-module</module>
<module>war-module</module>
<module>ear-module</module>
</modules>
</project>
Then, each of the child POMs would look like this:
ejb-module/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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.sonatype.mavenbook.multi</groupId>
<artifactId>simple-parent</artifactId>
<version>1.0</version>
</parent>
<artifactId>ejb-module</artifactId>
<packaging>ejb</packaging>
</project>
war-module/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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.sonatype.mavenbook.multi</groupId>
<artifactId>simple-parent</artifactId>
<version>1.0</version>
</parent>
<artifactId>war-module</artifactId>
<packaging>war</packaging>
<name>simple-webapp Maven Webapp</name>
<dependencies>
<dependency>
<groupId>org.sonatype.mavenbook.multi</groupId>
<artifactId>ejb-module</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</project>
ear-module/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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.sonatype.mavenbook.multi</groupId>
<artifactId>simple-parent</artifactId>
<version>1.0</version>
</parent>
<artifactId>ear-module</artifactId>
<packaging>ear</packaging>
<name>EAR module</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<version>2.10.1</version>
<configuration>
<ejbModule>
<groupId>org.sonatype.mavenbook.multi</groupId>
<artifactId>ejb-module</artifactId>
<bundleFilename>ejb-module.jar</bundleFilename>
</ejbModule>
<webModule>
<groupId>org.sonatype.mavenbook.multi</groupId>
<artifactId>war-module</artifactId>
<contextRoot>/foo</contextRoot>
</webModule>
</configuration>
</plugin>
</plugins>
</build>
</project>
parent QCforCC-parent :
<artifactId>QCforCC-parent</artifactId>
<packaging>pom</packaging>
...
...
<modules>
<module>QCforCC-ear</module>
<module>QCforCC-ejb</module>
<module>QCforCC-war</module>
</modules>
QCforCC-ear :
<artifactId>QCforCC-ear</artifactId>
<packaging>ear</packaging>
...
...
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<configuration>
<version>5</version>
<displayName>XXXXXXXX</displayName>
<modules>
<webModule>
<moduleId>WebModule_XXX</moduleId>
<groupId>${project.groupId}</groupId>
<artifactId>>QCforCC-war</artifactId>
<contextRoot>XXXXXXXX</contextRoot>
</webModule>
<jarModule>
<groupId>${project.groupId}</groupId>
<artifactId>QCforCC-ejb</artifactId>
</jarModule>
</modules>
</configuration>
</plugin>
</plugins>

Resources