maven cannot build child module from child directory - java

I have a maven project with a parent pom and child modules, structured like this:
root/pom.xml
root/parent/pom.xml
root/child1/pom.xml
root/child2/pom.xml
root/child2/child21/pom.xml
Every child pom and the root pom declare root/parent as their parent. child21 has child1 as a dependency.
When I try to execute mvn install from the child1 directory, maven successfully builds and installs the child1 jar. But when i execute mvn install from either the child2 or child21 directories, maven errors out with the following:
[ERROR] Failed to execute goal on project child21: Could not resolve dependencies for project groupId:child21:jar:0.0.1-SNAPSHOT: Failed to collect dependencies at groupId:child1:jar:0.0.1-SNAPSHOT: Failed to read artifact descriptor for groupId:child1:jar:0.0.1-SNAPSHOT: Could not find artifact groupId:parent:pom:0.0.1-SNAPSHOT in jme-repo (http://updates.jmonkeyengine.org/maven/) -> [Help 1]
I have tried googling for what might be wrong with my project structure with no luck. Can anyone help suggest ways to get child21 to build?
My poms contain:
Root
<parent>
<groupId>groupId</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>./parent/pom.xml</relativePath>
</parent>
<artifactId>root</artifactId>
<packaging>pom</packaging>
<modules>
<module>child1</module>
<module>child2</module>
</modules>
Parent
<groupId>groupId</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>groupId</groupId>
<artifactId>child1</artifactId>
<version>${project.version}</version>
</dependency>
...
</dependencies>
<dependencyManagement>
<repositories>
<repository>
<id>jme-repo</id>
<name>JME3 Official Maven Repo</name>
<url>http://updates.jmonkeyengine.org/maven/</url>
</repository>
</repositories>
<build>
<plugins>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>${java.source.version}</source>
<target>${java.target.version}</target>
</configuration>
</plugins>
</build>
Child 1
<parent>
<groupId>groupId</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>
<artifactId>child1</artifactId>
<packaging>jar</packaging>
<dependencies>...</dependencies>
Child 2
<parent>
<groupId>groupId</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>
<artifactId>child2</artifactId>
<packaging>pom</packaging>
<modules>
<module>child21</module>
</modules>
Child 21
<parent>
<groupId>groupId</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent/pom.xml</relativePath>
</parent>
<artifactId>child21</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>groupId</groupId>
<artifactId>child1</artifactId>
</dependency>
</dependencies>
UPDATE WITH SOLUTION
Based on the accepted answer below, I added the parent project as a module of the root pom:
<parent>
<groupId>groupId</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>./parent/pom.xml</relativePath>
</parent>
<artifactId>root</artifactId>
<packaging>pom</packaging>
<modules>
<module>parent</module>
<module>child1</module>
<module>child2</module>
</modules>
Then when developers build the project for the first time, the parent pom is installed. Subsequently they will be able to build the child2 and child21 projects independently.

This is a pretty awkward module structure, but it can still work. The problem is that when you are building module child21 (or child2), the child1 dependency is not a part of the current build, but is looked up in the repository. So is the parent of that dependency, which is the parent module. However, I assume, parent was never installed there - if you run mvn clean install on root, it does not build the parent, which is only referenced in the child modules by relative paths.
To fix it you must first install the parent POM into the repository. Run mvn install in the parent module. After that, build child1 - it will be installed into the repository as well. Now everything what is needed for building module child21 is available in the repository.

Change child21 to inherit from its parent - child2, see below:
<parent>
<groupId>groupId</groupId>
<artifactId>child2</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>

Related

Maven multi module project, but children have another parent

I encountered a multi module Maven project where the parent defines some child modules in the pom, but some of the child modules reference another parent. Something like this:
parent pom:
<groupId>test</groupId>
<artifactId>parentAAA</artifactId>
<packaging>pom</packaging>
<version>1.0</version>
<modules>
<module>module1</module>
<module>module2</module>
<module>module3</module>
</modules>
module1 pom:
<parent>
<groupId>test</groupId>
<artifactId>parentBBB</artifactId>
<version>2.0</version>
</parent>
<groupId>test</groupId>
<artifactId>module1</artifactId>
<version>1.0</version>
The project builds with maven 3.6.3 but the versions plugin fails.
Is such a configuration correct? (My assumption is that is isn't)

Why can't maven parse the expression in the parent's version?

I came across a problem with a maven project build.
My project structure is as follows
my-message
|
---my-message-api
|
--- my-message-provider
Below is the pom.xml code
my-message.pom
<parent>
<groupId>com.xiaofeng.my</groupId>
<artifactId>my-parent</artifactId>
<version>0.0.1</version>
</parent>
<artifactId>my-message</artifactId>
<version>${my-message.version}</version>
<packaging>pom</packaging>
<name>${project.artifactId}</name>
<properties>
<my-message.version>0.0.1-SNAPSHOT</my-message.version>
</properties>
<modules>
<module>my-message-api</module>
<module>my-message-provider</module>
</modules>
my-message-api.pom
<parent>
<groupId>com.msh.my</groupId>
<artifactId>my-message</artifactId>
<version>${my-message.version}</version>
<relativePath>../pom.xml</relativePath>
</parent>
my-message-provider.pom
<parent>
<groupId>com.msh.my</groupId>
<artifactId>my-message</artifactId>
<version>${my-message.version}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>my-message-provider</artifactId>
<dependencies>
<dependency>
<groupId>com.msh.my</groupId>
<artifactId>my-message-api</artifactId>
<version>${my-message.version}</version>
</dependency>
</dependencies>
maven install output
Failed to execute goal on project my-message-provider: Could not resolve dependencies for project
com.msh.my:my-message-provider:jar:0.0.1-SNAPSHOT: Failed to collect dependencies at com.msh.my:my-message-api:jar:0.0.1-SNAPSHOT:
Failed to read artifact descriptor for com.msh.my:my-message-api:jar:0.0.1-SNAPSHOT: Could not find artifact com.msh.my:my-message:pom:${my-message.version}
in nexus (http://nexus_url:8081/nexus/content/groups/public)
Why can't maven parse the expression in the parent's version? please help me
Because you can't use a variable in the specification of a parent in a module. Maven needs to be able to resolve the whole model structure before it can resolve variables.

Unable to use classes of one child module into another in multi-module maven project

I want to use the classes of one child module into another child module present in multi-module maven project. I have followed many existing solution. I am doing exactly same thing as in existing solution. But still it does not works.
Project structure:
Parent A: sampleproject
|-- child A: Gui
|-- child B: calculator
This is how pom.xml of parentA looks like:
<groupId>com.example</groupId>
<artifactId>sampleproject</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>Gui</module>
<module>calculator</module>
</modules>
pom.xml of child A looks like:
<parent>
<groupId>com.example</groupId>
<artifactId>sampleproject</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>Gui</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>calculator</artifactId>
<version>${project.version}</version>
<type>jar</type>
</dependency>
<dependencies>
pom.xml of child B looks like:
<parent>
<groupId>com.example</groupId>
<artifactId>sampleproject</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>calculator</artifactId>
<packaging>jar</packaging>
When I perform mvn install on parent project. jar files are created in calculator/target/name_of_jar.jar and Gui/target/name_of_jar.jar. But when I check in maven dependencies of Gui project, only directory of calculator is created rather than jar file.
Here is image of maven dependencies in Gui project.
Links I have followed: use-a-class-from-the-other-child-module-in-maven and share-classes-within-modules-in-maven-project

Use of environment variable in POM.xml doesn't work

I am trying to pull out the version number of the POM and all the dependencies to a environment variable. For example:
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven- 4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema- instance">
<modelVersion>4.0.0</modelVersion>
<artifactId>example-assembly</artifactId>
<name>example-assembly</name>
<properties>
<current.version>${env.CURRENTVERSION}</current.version>
</properties>
<dependencies>
<dependency>
<groupId>com.example.demo</groupId>
<artifactId>exceptions</artifactId>
<version>${current.version}</version>
</dependency>
<dependencies>
<packaging>war</packaging>
<version>${current.version}</version>
</project>
With the above setup, when I run mvn clean command I am getting following error:
dependencies.dependency.version for example-assembly:war must be a valid version but is '${env.CURRENTVERSION}'
Any idea about what could be the issue?
Note: I am running maven in windows OS
There is a better alternative for updating Versions in pom.xml than using environment variables inside pom.xml: Versions Maven Plugin. This allows you to change pom.xml using maven command line.
Sample scenario
Project Structure:
+ P (Parent - Version 1.0.0-SNAPSHOT)
-- C1 (Child Project 1 - Version 1.0.0-SNAPSHOT)
-- C2 (Child Project 2 - Version 1.0.0-SNAPSHOT also depends on C1)
Task
You want to change version in all pom.xml files to 1.0.1-SNAPSHOT
Parent pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>sample</groupId>
<artifactId>p</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>Parent</name>
<packaging>pom</packaging>
<modules>
<module>c1</module>
<module>c2</module>
</modules>
</project>
Child Project 1 pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<artifactId>c1</artifactId>
<name>Child Project 1</name>
<packaging>jar</packaging>
<parent>
<groupId>sample</groupId>
<artifactId>p</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
</project>
Child Project 2 pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<artifactId>c2</artifactId>
<name>Child Project 2</name>
<packaging>jar</packaging>
<parent>
<groupId>sample</groupId>
<artifactId>p</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>sample</groupId>
<artifactId>c1</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
Command
Command to set new version in all pom.xml files
mvn -B -DnewVersion=1.0.1-SNAPSHOT versions:set
In case new version is represented by environment variable CURRENTVERSION
mvn -B -DnewVersion=$CURRENTVERSION versions:set
Here -B means --batch-mode (so new version won't be prompted on console)
Resultant files would be
Parent pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>sample</groupId>
<artifactId>p</artifactId>
<version>1.0.1-SNAPSHOT</version>
<name>Parent</name>
<packaging>pom</packaging>
<modules>
<module>c1</module>
<module>c2</module>
</modules>
</project>
Child Project 1 pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<artifactId>c1</artifactId>
<name>Child Project 1</name>
<packaging>jar</packaging>
<parent>
<groupId>sample</groupId>
<artifactId>p</artifactId>
<version>1.0.1-SNAPSHOT</version>
</parent>
</project>
Child Project 2 pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<artifactId>c2</artifactId>
<name>Child Project 2</name>
<packaging>jar</packaging>
<parent>
<groupId>sample</groupId>
<artifactId>p</artifactId>
<version>1.0.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>sample</groupId>
<artifactId>c1</artifactId>
<version>1.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
The variable you define has the scope in the same pom.xml only and cannot be used in any other pom.
If you want to define the variable globally define it in settings.xml of maven.
Define the variable env.CURRENTVERSION somewhere in the the same pom, root pom or settings.xml
or else provide the exact version value in its place.
<properties>
<current.version>'your correct version'</current.version>
</properties>
e.g.
<properties>
<current.version>1.0.0</current.version>
</properties>

Maven module hierarchy

I have two modules(maven projects) in parent maven project: android-module and server-module. This two modules uses identical models(POJO - classes). So I want extract models from both modules and make new module in parent project.
So I whant this:
--Project
|--android-module
| -- pom.xml
|--server-module
| -- pom.xml
-- pom.xml
remake to this:
--Project
|--android-module
| -- pom.xml
|--server-module
| -- pom.xml
|--models-module
| -- pom.xml
-- pom.xml
At the same time I want to root pom.xml compiles and build jar from models-module and store jar in my local repository. Then child pom.xml's were taking it from the repository and included in the android and server modules.
Question: How to tell maven to build and store jar in my local repository automatically.
Is it possible? If no - please, give me some ideas.... Thnks
Just run mvn install. This will install the packaged jar into your local repo in ~/.m2
Make sure you run maven from the root pom
The solution is found. It was much easier.
parent pom.xml:
...
<groupId>com.lutshe</groupId>
<artifactId>doiter</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>doiter-android</module>
<module>doiter-server</module>
<module>doiter-model</module>
</modules>
...
child1 (android project) pom.xml:
...
<parent>
<groupId>com.lutshe</groupId>
<artifactId>doiter</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.lutshe</groupId>
<artifactId>doiter-android</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>apk</packaging>
<dependencies>
<dependency>
<groupId>com.lutshe</groupId>
<artifactId>doiter-models</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
...
child2 (server) pom.xml:
...
<parent>
<groupId>com.lutshe</groupId>
<artifactId>doiter</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.doiter.server</groupId>
<artifactId>doiter-server</artifactId>
<version>0.1.0</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>com.lutshe</groupId>
<artifactId>doiter-models</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
...
child3 (shared models) pom.xml:
...
<parent>
<groupId>com.lutshe</groupId>
<artifactId>doiter</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.lutshe</groupId>
<artifactId>doiter-model</artifactId>
<version>1.0-SNAPSHOT</version>
...

Categories

Resources