Maven nested dependency is not accessible - java

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.

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>

How do I manage version numbers with modularized Maven projects?

I have a fairly typical plugin architecture that looks something like this (just larger):
project
core
data
main
ui
The parent project has a version number defined, is packaged as a pom and defines modules in it's pom.xml:
<groupId>group</groupId>
<artifactId>project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
...
<modules>
<module>core</module>
<module>data</module>
<module>main</module>
<module>ui</module>
</modules>
All of the sub-modules have many references to the parent's version number everywhere. Here is the an example of what the main module looks like to give you an idea:
<parent>
<groupId>group</groupId>
<artifactId>project</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>group</groupId>
<artifactId>project.main</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>group</groupId>
<artifactId>group.core</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>group</groupId>
<artifactId>group.data</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>group</groupId>
<artifactId>group.ui</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
We're getting tired of having to change the version number over, and over, and over with each release in every parent block, in every artifact block, and in every dependency block for each and every module. On a few occasions, someone used search/replace which hit other files and messed up the build. We tried using properties, but that doesn't work inside the parent definitions for some nonsensical reason.
The version number defined in the parent is the only place we care to manage. We don't even need the sub-modules to even HAVE versions (or artifacts, for that matter). We can do this in our other Ant projects. We can do this in our other Gradle projects. I can't imagine this being impossible in Maven, so I am guessing we are missing something.
How can we define the project's version number in one place, and have that used in all of the parent, artifact, and dependency sections in our modules?
Version maven plugin offers the possibility of changing the subprojects version in one shot. After including the plugin:
mvn versions:set -DnewVersion=<your version>
And if everything is correct:
mvn versions:commit

Properties defined in parent pom cannot be resolved/updated in child pom

The parent pom:
<modelVersion>4.0.0</modelVersion>
<groupId>xx.xxxx.xxxx.xx</groupId>
<artifactId>parent-pom</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<properties_deinfed_in_parent_pom>1.0.2-SNAPSHOT</properties_deinfed_in_parent_pom>
</properties>
The child pom:
<parent>
<groupId>xx.xxxx.xxxx.xx</groupId>
<artifactId>parent-pom</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>child-pom</artifactId>
<packaging>war</packaging>
<version>${properties_deinfed_in_parent_pom}</version>
which includes the parent pom, if I change the property properties_deinfed_in_parent_pom in parent pom, the version in child pom won't be updated. The only way I can update is using -Dxxx=value in maven command. I also checked the effective pom, it's also not updated. So will this idea work as my expectation, or what I thought was wrong.
I use Maven 3.3.x, IntelliJ 2018.1
The parent pom need to have the list of modules specified. Add the following to the parent pom
<modules>
<module>child-pom</module>
</modules>

Can't use classes from different Maven modules

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.

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