Project have next structure:
root
|
+--Module 1
| |
| +--Submodule_1
| |
| +--Submodule_2
| |
| +--Submodule_N
|
+--Module 2
Module 2 depend on Module 1 and expected access to classes from submodules 1..N
Root pom.xml:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>root</artifactId>
<version>master</version>
<packaging>pom</packaging>
<modules>
<module>Module_1</module>
<module>Module_2</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
</project>
Module 1 pom.xml:
<project>
<parent>
<groupId>com.example</groupId>
<artifactId>root</artifactId>
<version>master</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Module_1</artifactId>
<packaging>pom</packaging>
<modules>
<module>Submodule_1</module>
<module>Submodule_2</module>
...
<module>Submodule_N</module>
</modules>
</project>
Submodule_N pom.xml:
<project>
<parent>
<groupId>com.example</groupId>
<artifactId>Module_1</artifactId>
<version>master</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Submodule_N</artifactId>
</project>
Module 2 pom.xml:
<project>
<parent>
<groupId>com.example</groupId>
<artifactId>root</artifactId>
<version>master</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Module_2</artifactId>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>Module_1</artifactId>
<version>master</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
So this configuration fail with error package com.example.submodule_n.x.y does not exist.
If add dependency from module 1 to submodule_n than package will be found but maven fail with error ...is referencing itself.
One working case if add dependency from module 2 to submodule_n. But expected way when module 2 will have only one dependency to module 1 for include all submodules from module 1.
It is can do gradle, but I don't have any ideas how it implement using maven.
One working case if add dependency from module 2 to submodule_n. But expected way when module 2 will have only one dependency to module 1 for include all submodules from module 1
That is your expectations that are actually not valid.
The purpose of configuration like:
<modules>
<module>Submodule_1</module>
<module>Submodule_2</module>
...
<module>Submodule_N</module>
</modules>
is to somehow organise project structure, it have nothing in common with dependencies between java libraries (though, it affects build lifecycle), moreover, the configuration like:
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>Module_1</artifactId>
<version>master</version>
<scope>compile</scope>
</dependency>
</dependencies>
in general does not make sense because library may not depend on pom - actually that just tells maven to build Module_2 after Module_1.
Summarising statements above: if Module_2 depends on Submodule_N you must explicitly define that dependency in pom.xml
Related
I have a multi module maven project with three different modules Module-Data, Module-Domain, Module-Web. All three projects are spring boot projects, however Module-Web is the web component of the project that handles everything web oriented which I want to build a war file for. I have a parent project with the following pom file which contains no code.
<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.somename</groupId>
<artifactId>My-Project</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>module-data</module>
<module>module-domain</module>
<module>modele-web</module>
</modules>
Module-Domain depends on Module-Data and Module-Web depends on both Module-Data and Module-Domain. The problem I'm having is that when I try to build the project using maven it fails when building the Module-Domain with the following erros:
package com.somename.data.model does not exist // class file with this error
Module-Domain class files that imports from the Module-Data project fails with this error. I suspect this is because maven is not adding the Module-Data jar to the Module-Domain when building although its referenced in its pom file. How can I solve this problem and generate a war file with all dependencies?
Module-Domain pom.xml:
<dependency>
<groupId>com.somename.data</groupId>
<artifactId>module-data</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
Module-Web pom.xml
<dependency>
<groupId>com.somename.data</groupId>
<artifactId>module-data</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.somename.domain</groupId>
<artifactId>module-domain</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
This is a simple straight-forward approach that you are using. Should not cause a problem.
Module-Domain pom.xml:
<parent>
<groupId>com.somename</groupId>
<artifactId>My-Project</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>com.somename.data</groupId>
<artifactId>module-data</artifactId>
<version>0.0.1-SNAPSHOT</version> <!-- Make sure this version is correct -->
</dependency>
</dependencies>
Module-Web pom.xml:
<parent>
<groupId>com.somename</groupId>
<artifactId>My-Project</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>com.somename.domain</groupId>
<artifactId>module-domain</artifactId> <!-- pulls "module-data" as well : transitive dependency -->
<version>0.0.1-SNAPSHOT</version> <!-- Make sure this version is correct -->
</dependency>
</dependencies>
Do maven clean compile on the parent project that would build all the modules.
If you still see any compilation issues, you would need fix the source code.
I have a maven multi-module project as follows:
app
|- pom.xml
|- child1
|-pom.xml
|-other files
|-child2
|- pom.xml
|- aggregator.xml
The files are as follows:
pom.xml in app
<modules>
<module>child1</module>
<module>child2/aggregator.xml</module>
</modules>
aggregator.xml in child2
<modules>
<module>./pom.xml</module>
</modules>
pom.xml in child2
contains the list of dependencies
When I run the command mvn clean inside the app directory, it gives the following error:
Cannot resolve symbol child2/aggregator.xml
How do I resolve the above error?
Also, if I wish to do the same in Intellij, how can I do that?
In your comment you wrote Actually, there are several pom.xmls inside the child2 directory. This way isn't possible. Every module has one pom.xml.
I'll give you an example for a multi module project, in which there is one child module which has children.
appRoot
| pom.xml
|
+ child1
| pom.xml
|
+ child2
| pom.xml
|
+ child2a
| pom.xml
|
+ child2b
| pom.xml
appRoot pom.xml:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>appRoot</artifactId>
<version>1.0.0</version>
<modules>
<module>child1</module>
<module>child2</module>
</modules>
<dependencyManagement>
<dependencies>
<!-- declare dependencies which are common to all modules -->
<!-- including versionId -->
</dependencies>
</dependencyManagement>
</project>
child1 pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.example</groupId>
<artifactId>appRoot</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>child1</artifactId>
<version>1.0.0</version>
<dependencies>
<!-- declare dependencies from parent dependency management -->
<!-- without versionId (it's in the parent) -->
<!-- declare dependencies which are module specific -->
<!-- including versionId -->
</dependencies>
</project>
child2 pom.xml:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.example</groupId>
<artifactId>appRoot</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>child2</artifactId>
<version>1.0.0</version>
<modules>
<module>child2a</module>
<module>child2b</module>
</modules>
</project>
If it's necessary, you can add a <dependencies> and/or <dependencyManagement> section in child2.
child2a and child2b pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.example</groupId>
<artifactId>child2</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>child2a</artifactId>
<!-- <artifactId>child2b</artifactId> -->
<version>1.0.0</version>
<dependencies>
<!-- declare dependencies from parent dependency management -->
<!-- without versionId (it's in the parent) -->
<!-- declare dependencies which are module specific -->
<!-- including versionId -->
</dependencies>
</project>
I have a project structure like below.In aggregator POM project1 and project 2 are defined as modules.Now if i want to add a maven property that can be accessed in all the projects how can i do it?.
What is the best project structure in this case.?
If i define property like <temp.dir>data</temp.dir> in the aggregator POM then it is not available in project1 pom.xml and project2 POM.xml.I have to duplicate the same property in both the POM's.
project
- project1
- - pom.xml ---- has parent POM as project A
- project2
- - pom.xml --- has parent POM as project B
- pom.xml (Aggregator POM)
UPDATE:To clarify more project1 pom and project 2 has different parent POM's.So aggregator POM cannot be set as parent.
You need to set the aggregator pom as the parent of project1 and project2.
eg. in project1 and project2 poms add:
<parent>
<groupId>com.agr</groupId>
<artifactId>project-aggregator</artifactId>
<version>1.0.0</version>
</parent>
EDIT:
I understand that project1 and project2 have different parent poms.
The only solution i know about to achieve what You want is to store the properties in parent pom.
I can think only of one solution, to make an inheritance chain:
Project2Parent:
<parent>
<groupId>com.test</groupId>
<artifactId>Project1Parent</artifactId>
<version>0.0.1</version>
</parent>
<artifactId>Project2Parent</artifactId>
<version>0.0.1</version>
Aggregator:
<parent>
<groupId>com.test</groupId>
<artifactId>Project2Parent</artifactId>
<version>0.0.1</version>
</parent>
<artifactId>Aggregator</artifactId>
<version>0.0.1</version>
Project1
<parent>
<groupId>com.test</groupId>
<artifactId>Aggregator</artifactId>
<version>0.0.1</version>
</parent>
<artifactId>project1</artifactId>
<version>0.0.1</version>
Project2
<parent>
<groupId>com.test</groupId>
<artifactId>Aggregator</artifactId>
<version>0.0.1</version>
</parent>
<artifactId>project2</artifactId>
<version>0.0.1</version>
Here is aggregator's pom:
<groupId>y</groupId>
<artifactId>y</artifactId>
<version>0.0.1</version>
<packaging>pom</packaging>
<modules>
<module>y1</module>
<module>y2</module>
</modules>
<properties>
<x>1</x>
</properties>
This is y1 effective pom (generated by Eclipse):
<parent>
<groupId>y</groupId>
<artifactId>y</artifactId>
<version>0.0.1</version>
</parent>
<groupId>y1</groupId>
<artifactId>y1</artifactId>
<version>0.0.1</version>
<properties>
<x>1</x>
</properties>
As you can see property x declared in parent is inherited by child.
Good day,
I am getting an error saying: 'The projects in the reactor contain a cyclic reference'.
Parent pom.xml:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.solveit.cmr</groupId>
<artifactId>cmr-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>cmr-parent</name>
<modules>
<module>cmr-core</module>
</modules>
<dependencies>
<dependency>
<groupId>com.solveit.cmr.core</groupId>
<artifactId>cmr-core</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
child pom:
<modelVersion>4.0.0</modelVersion>
<artifactId>cmr-core</artifactId>
<name>cmr-core</name>
<groupId>com.solveit.cmr.core</groupId>
<parent>
<groupId>com.solveit.cmr</groupId>
<artifactId>cmr-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
How can I fix this problem?
Thank you
The <modules> section tell maven the hierarchy between the parent pom and childs pom.
The parent should contain all the common section to all the modules.
such as <dependencyManagement>, <plugins> and <properties>
I have a fairly simple maven-ized Java project, but am having trouble getting my head around it.
My parent module defines a lot of Java classes (and dependencies) that I expect to be useful for several child modules. One of the child modules is dedicated to deploying a web app, so it needs a few extra classes (the servlets) plus everything from the parent module.
The file structure looks like this
- parent
- src
- pom.xml
- child
- src
- pom.xml
My parent pom looks like this:
<project>
<groupId>my.group</groupId>
<artifactId>parent</artifactId>
<version>0.0.1</version>
<packaging>pom</packaging>
...
<modules>
<module>child</module>
</modules>
</project>
And the child looks like this:
<project>
<artifactId>child</artifactId>
<packaging>war</packaging>
<parent>
<artifactId>parent</artifactId>
<groupId>my.group</groupId>
<version>0.0.1</version>
</parent>
...
</project>
Is this all I need to have the child know about the classes and dependencies defined in parent? It doesn't seem to be: eclipse gives compile errors, and running mvn clean package from parent folder or child folder results "cannot find symbol" messages any time a class from parent is mentioned.
What am I doing wrong?
I'd change the structure of your project like this:
parent (pom)
core (jar, with all the classes that used to be in parent)
child (war, depends on core)
Parent:
<project>
<groupId>my.group</groupId>
<artifactId>parent</artifactId>
<version>0.0.1</version>
<packaging>pom</packaging>
<modules>
<module>core</module>
<module>child</module>
<!-- possibly more modules... -->
</modules>
</project>
Core:
<project>
<parent>
<groupId>my.group</groupId>
<artifactId>parent</artifactId>
<version>0.0.1</version>
</parent>
<artifactId>core</artifactId>
<packaging>jar</packaging>
</project>
Child:
<project>
<parent>
<groupId>my.group</groupId>
<artifactId>parent</artifactId>
<version>0.0.1</version>
</parent>
<artifactId>module1</artifactId>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>my.group</groupId>
<artifactId>core</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
Since your parent module's packaging is "pom", no jar file will be provided and no .class file from that will be accessible to other modules. Try changing it to "jar" and give it another try.
Although it's not a good practice to have a parent as "jar". I'd stick to the "pom" parent and probably create a new "core" or "common" child and make my "war" depend on it.
Try to add an internal dependency in child module pom, so it is familiar with its parent
<dependency>
<groupId>my.group</groupId>
<artifactId>parent</artifactId>
<version>0.0.1</version>
</dependency>
The first thing you should do is to define your dependencies within a dependencyManagmeent block in your parent like this:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>1.0</version>
</dependency>
...
</dependencies>
</dependencyManagement>
and furthermore in your child you should say which dependency your child would like to use as dependency:
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<!-- No version given. See dependencyManagement -->
</dependency>
...
</dependencies>