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>
Related
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
I want to understand if Parent POM and Super POM are same or are there still differences.
Take below maven poms, I declare a parent pom as below:
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.demo</groupId>
<artifactId>deps</artifactId>
<packaging>pom</packaging>
<version>0.0.1-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<!-- not relevant for this question -->
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.12</version>
</dependency>
</dependencies>
</project>
Now I declare a child pom as below:
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.demo</groupId>
<artifactId>deps2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>com.demo</groupId>
<artifactId>deps</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<dependencies>
<!-- not relevant for this question -->
</dependencies>
</project>
Now deps is the parent pom for deps2. I am not sure if I can also call deps as super pom for deps2.
Which of the below inheritance hierarchy is correct
dep2 --> deps end (NO Maven provided super pom)
dep2 --> deps --> Maven provided super pom end
Option 2, because all models implicitly inherit from the Super POM.
deps is a parent for deps, but not the Super POM.
This is according to the definitions on the website.
What is more ... if you inspect the effective POM, you will see that it will always inherit from the Super POM on the MVN website.
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>