Cyclic reference error in maven - java

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>

Related

Maven: Dependency to pom module is not include submodules from it

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

How to develop a Maven Multi-module application using the Spring Boot framework

I have a maven multi-module Java project that runs perfectly, until I try to include the Spring Boot framework. The main module, called core, gets called OK, but all the rest are unable to implement the interface I declared in Core.java.
This error gets thrown:
[ERROR] /F:/mvnmodularapp/module1/src/main/java/service/impl/ModuleServiceImpl.java:[12,30] cannot find symbol
[ERROR] symbol: class Service
[ERROR] /F:/mvnmodularapp/module1/src/main/java/service/impl/ModuleServiceImpl.java:[13,5] method does not override or implement a method from a supertype
The project structure:
mvnmodularapp/
/pom
mvnmodularapp/core/
/src
/target/core-1.0-SNAPSHOT.jar
mvnmodularapp/module1
/src
/target/module1-1.0-SNAPSHOT.jar
THe file/directory structure:
core/src/java/service/
Service.java
core/src/java/service/impl
CoreServiceImpl.java
module1/src/java/service/impl
ModuleServiceImpl.java
Service.java
public interface Service {
String getName();
}
CoreServiceImpl.java in core
#Service
public class ServiceImpl implements Service {
#Override
public String getName() {
return "Hi. You called me from ServiceImpl in Core";
}
}
ModuleServiceImpl.java in module1
#Service
public class ModuleServiceImpl implements Service {
#Override
public String getName() {
return "Hi. You called me from ModuleServiceImpl in module1, but I can\'t pick up right now. Sorry";
}
}
THE POMS
mvnmodularapp 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>com.mvnmodularapp</groupId>
<artifactId>mvnmodularapp</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>core</module>
<module>module1</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.3.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
</project>
core 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">
<parent>
<artifactId>mvnmodularapp</artifactId>
<groupId>com.mvnmodularapp</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>core</artifactId>
<version>1.0-SNAPSHOT</version>
<name>Core</name>
<description>SudenGut application</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<start-class>main</start-class>
<java.version>1.8</java.version>
<tomcat.version>8.0.24</tomcat.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--- this will not be enough to provide a cool app :) -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
module1 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">
<parent>
<artifactId>mvnmodularapp</artifactId>
<groupId>com.mvnmodularapp</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>module1</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<start-class>baseview.impl.BaseViewImpl.ModuleServiceImpl</start-class>
<java.version>1.8</java.version>
<tomcat.version>8.0.24</tomcat.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--- this will not be enough to provide a cool app :) -->
<dependency>
<groupId>com.mvnmodularapp</groupId>
<artifactId>core</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Dependencies between modules are correctly declared but you have one thing that is not configured as required.
I am not sure it will solve your problem but it could.
You declare in each module :
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
It should be required only for the module which bootstraps the Spring Boot application.
If you want have multiple web applications in the same Spring Boot container, you could read this question.
As you say that it works before adding Spring Boot I think that the problem should be solved with previous recommandation.
But if it is not enough, below are other guessworks which could be the cause of the compilation error. I rely on this error message :
[ERROR]
/F:/mvnmodularapp/module1/src/main/java/service/impl/ModuleServiceImpl.java:[12,30]
cannot find symbol [ERROR] symbol: class Service
The Service class is not imported in ModuleServiceImpl.
If I rely on what you write in your question, you should add :
import service.Service in the imports of ModuleServiceImpl.
The core module doesn't create a JAR with the service.Service class.
So, importing it doesn't solve the problem of the module1 module.
You should perform a mvn clean install from the core module and check that the jar contains the compiled class : service.Service in the good package.

Defining maven submodules in pom.xml

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>

How to specify maven properties in a aggregator POM?

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.

Maven include parent classes

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>

Categories