Can't use classes from different Maven modules - java

Need to create a multi module maven project which consist of a registration module and main project. The problem is that it's impossible to use classes declared in different modules.
e.g.: I have a ParentClaz in my parent's src/main/java dir and ChildClaz in child's src/main/java dir. Right now it's not possible to use neither ParentClaz in ChildClaz nor vice versa.
The project's structure looks like this:
+-- AdminPortal <- parent root
+-- registration <- child root
-- pom.xml <- child pom
-- pom.xml <- parent pom
my AdminPortal POM:
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>AdminPortal</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<name>AdminPortal</name>
<url>http://maven.apache.org</url>
<modules>
<module>registration</module>
</modules>
Here's child POM:
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.example</groupId>
<artifactId>AdminPortal</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.example.AdminPortal</groupId>
<artifactId>registration</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>registration</name>
<url>http://maven.apache.org</url>
How can this problem be solved?

Your parent pom has packaging type pom, this is not jar. This is special aggregator module. All java code should be located in jar modules.
Module with packaging type pom cant generate artifacts like jar, war or ear.
Maven by Example - The Simple Parent Project
The parent project doesn’t create a JAR or a WAR like our previous projects; instead, it is simply a POM that refers to other Maven projects.
To use Classes from one module in other module use maven dependency.
Typical project looks like this:
* administration project (pom)
* registration (jar)
* portal (war)

Child can use parent dependencies, try to add this to parent
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency>
</dependencies>
and make this class in child
import org.apache.log4j.Logger;
public class Test {
public static void main(String[] args) {
Logger.getLogger(Test.class);
}
}
and you will see that it compiles.

Related

How to make the Maven child project to have different version than the parent?

I am very new to Maven, and I am creating a Maven parent and child project. I want the child project to have a different version than the parent, but if I change the version, then I am getting the error Cannot resolve for some of the dependencies.
How can I have a have a parent version different than the child version?
Following are the current properties I have, which are working pretty fine:
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.parent-test</groupId>
<artifactId>io.parent-test</artifactId>
<version>0.9.1-SNAPSHOT</version>
<relativePath></relativePath>
</parent>
<artifactId>test-project-converter</artifactId>
<name>test-project</name>
<description>Test Project</description>
If I change the properties to include the different version for child then I get the error:
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.parent-test</groupId>
<artifactId>io.parent-test</artifactId>
<version>0.9.1-SNAPSHOT</version>
<relativePath></relativePath>
</parent>
<version>0.9.2-SNAPSHOT</version>
<artifactId>test-project-converter</artifactId>
<name>test-project</name>
<description>Test Project</description>
I have the following dependencies based on the version that is throwing the error:
<dependency>
<groupId>io.parent-dep</groupId>
<artifactId>parent-dev</artifactId>
<version>${project.version}</version>
</dependency>
I tried to look into some of the responses online and made modifications to my parent project to include the properties:
<properties>
<revision>0.9.2-SNAPSHOT</revision>
</properties>
and accordingly, change the child project to include the version <version>${revision}</version> but it's not working as expected.
Can someone please let me know how can I create a different snapshot version for my child project while keeping the parent project same?
I think because you are building wrong order of child and parent project. When you change the version of child project, you should first re-build child project with new version -> new jar file name (with old parent jar file if in the child project have parent dependency) then update the version of child dependency in the pom file of parent project and re-build parent project, then re-build child project again with the new parent jar file (the same version but include different child jar file).
I was able to fix it by providing the parent version ${project.parent.version} to the dependencies coming from the parent.
I tried this, and everything worked fine.
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.parent-test</groupId>
<artifactId>io.parent-test</artifactId>
<version>0.9.1-SNAPSHOT</version>
<relativePath></relativePath>
</parent>
<version>0.9.2-SNAPSHOT</version>
<artifactId>test-project-converter</artifactId>
<name>test-project</name>
<description>Test Project</description>
<dependencies>
<dependency>
<groupId>io.parent-dep</groupId>
<artifactId>parent-dev</artifactId>
<version>${project.parent.version}</version>
</dependency>
</dependencies>

Maven child module in parent pom as dependency

I'm trying to create a maven spring-boot project with multiple modules. I have created a parent module with packaging type pom and many children submodules with packaging type jar.
So my parent's pom.xml looks like:
<groupId>Creator</groupId>
<artifactId>DPAI</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>starter</module>
<module>DatabaseApi</module>
...
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
One of submodules: starter contains only starting class annotated with #SpringBootApplicatoion and in its pom.xml there is a section with other child artifacts like:
<parent>
<artifactId>DPAI</artifactId>
<groupId>Creator</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>starter</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>Creator</groupId>
<artifactId>DatabaseApi</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
...
</dependencies>
So I'm trying to do some refactoring and move Main.class and all dependencies to my parent's pom, but it doesn't compile with error with message that my dependencies referencing itself.
In my opinion, the problem is that my parent pom contains section with it's own submodules. Parent of that submoduls is the same pom, where I try to add described dependencies
The parent.pom can't contain any java code, only Maven specifics e.g. See: https://howtodoinjava.com/maven/maven-parent-child-pom-example/#parent-content
Maybe tell us, what you want to achieve.
In a Maven multi module project you usually have a parent Pom (with packaging Pom) and several modules at the same level as you already set your project up.
Build the modules without dependecies on your code first, the the dependent modules: In your parent Pom change the order of the modules to
<modules>
<module>DatabaseApi</module>
<module>starter</module>
...
</modules>
So I'm trying to do some refactoring and move Main.class and all
dependencies to my parent's pom
I dont think this is possible. Your parent pom is actually of type pom, meaning you're not actually supposed to have any java code in it. Its meant to hold the versions of jars used in your child modules. You can relate this to the spring-boot-parent module. When we declare the spring-boot-parent module in a spring boot project, your adding your project as a child of the spring-boot-parent. And the parent will manage the versions of all of your dependencies.
I think the best way forward would be to maintain all your service related code in your spring-boot module. Filters, controllers,etc. The other stuff like your jdbc, integration layers can be maintained in other child modules and then referred to the spring module as jar references similar to your example.
So I'm trying to do some refactoring and move Main.class and all
dependencies to my parent's pom,
I'm not 100% sure if Maven would support something like the following in the parent POM itself:
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>DatabaseApi</artifactId>
<version>${project.version}</version>
</dependency>
...
</dependencies>
But for sure it won't support Java classes in a Module with pom-packaging (such as parent modules or multi-module modules). The compiler:compile goal etc. are not bound to any phase for pom-packaging by default. In other words: Maven does not compile Java classes for pom-modules by default.
My recommendation:
Keep the SpringBootApplication in a Java-based module. For Spring MVC/ WebFlux application I usually create a "-web" module with:
SpringBootApplication
web service controllers
http/ web filters
global configs such as: security, swagger, async
application.yml
...
It's also the module where I configure the Spring Boot Plugin to create an executable JAR.

Maven nested dependency is not accessible

I have a maven project and in the parent POM and I have declared some dependencies inside this parent POM. This POM is used within the child POM as shown in the code snippet. When compiling the Child project, IntelliJ complains that it cannot find an interface used within the parent project.This interface is declared within the dependency "anotherApp" in the parent POM.
My understanding about Maven dependencies is that, since I have declared the dependency in Parent POM, it should get inherited in the child POM as well and child should be able to access these dependencies and their classes / interfaces without an issue.
I tried adding the dependency inside dependencyManagement tag in parent POM. But cannot achieve what I expect to get. I also looked into the dependency trees of both parent and child projects. In parent, dependency tree shows anotherApp as its dependency, but in child, only parent is shown as a dependency, anotherApp is not shown as a dependency came through parent.
This is how my parent POM looks like
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>it.app</groupId>
<artifactId>commonParent</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../CommonParent/pom.xml</relativePath>
</parent>
<groupId>com.app</groupId>
<artifactId>parent</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>com.myapp</groupId>
<artifactId>anotherApp</artifactId>
<version>2.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
This is how my child POM looks like
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>it.app</groupId>
<artifactId>commonParent</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../CommonParent/pom.xml</relativePath>
</parent>
<groupId>com.app</groupId>
<artifactId>child</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>com.app</groupId>
<artifactId>parent</artifactId>
</dependency>
</dependencies>
</project>
There is an interface Foo declared inside "anotherApp". This interface is accessible by the parent project. But child project cannot access this interface. IntelliJ complains that it cannot access this interface.
Two things that need to be corrected:
The parent POM should have <packaging>pom</packaging>.
The child project should not use the parent POM as dependency, but add it in the <parent> tag.

Creating a object for a class which is in jar

I have two projects. Project B is maven dependency in project A.I have to use a pojo class of project B in project A
Note:- I don't want to add the jar in build properties because in production it will be a issue
Its simple, you can packaging the project A as a jar and add this dependency as a provided scope in project B.
For example:
pom.xml (Project A):
<project>
...
<groupId>com.myproject.easy</groupId>
<artifactId>commom-lib</artifactId>
<version>0.1</version>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
</project>
pom.xml (Project B - Needs to use some Pojo Class from Project A):
<project>
...
<dependencies>
<dependency>
<groupId>com.myproject.easy</groupId>
<artifactId>commom-lib</artifactId>
<version>0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
It won't throw exception on your application server, cause provided scope means the jar used as a dependency in project B going to be on classpath during runtime.

Run a multi-module Maven project

This is a basic question, I'm just not really familiar with maven multi-module structures. Say, I have a web application. And I want to connect some modules to it (some services). Do I need to make a web app just one of the modules, dependent from some others, and then run it? At first I thought I could run the whole project, but this option turns out to be inactive in my IDE (I'm using NetBeans now), which made me think I should run something like a main module (a web app in this case). Is it so? Thanks in advance.
If you have a multi-module project you need a structure like the following which will also be represented by the folder structure as well.
+-- root (pom.xml)
+--- module-1
+--- module-2
+--- module-war
Whereas the root module contains a thing like this:
<project ..>
<groupId>com.test.project</groupId>
<artifactId>parent</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>module-1</module>
<module>module-2</module>
<module>module-war</module>
</modules>
</project>
In the module-1 your pom should look like this:
<project ..>
<parent>
<groupId>com.test.project</groupId>
<artifactId>parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>module-1</artifactId>
dependencies for the module
</project>
in module-2 it look more or less the same..and in the war module it looks like:
<project ..>
<parent>
<groupId>com.test.project</groupId>
<artifactId>parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<packaging>war</packaging>
<artifactId>module-war</artifactId>
dependencies for the module
</project>
If you have dependencies between the modules for example module-1 depends on module-2 it looks like the following in module-1:
<project ..>
<parent>
<groupId>com.test.project</groupId>
<artifactId>parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>module-1</artifactId>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>module-2</artifactId>
<version>{project.version}</version>
</dependency>
..other dependencies..
</dependencies>
</project>
To build and package your project you will go to parent folder and do simply a
mvn clean package

Categories