Why Maven doesn't install dependencies in multimodule project? - java

My project structure (multi module) is like this
parent
projectA
projectB
... other modules
parent also actually has a parent (Spring Boot).
I have set up a Jenkins jobs to compile & test on every commit, so it runs:
mvn -f pom.xml clean install
And that all works fine. ProjectB depends on ProjectA (which is like a common classes type of project) and is a Spring boot application. So the dependency information is the regular:
<dependency>
<groupId>Group</groupId>
<artifactId>ProjectA</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
ProjectB has a separate job in Jenkins to build the deployable jar file and deploy it to server. So the command there is:
mvn -f ProjectB/pom.xml clean install antrun:run
This fails with a message like:
[WARNING] The POM for Group:ProjectB:1.0-SNAPSHOT is missing, no dependency information available
...
[ERROR] Failed to execute goal on project host-api: Could not resolve dependencies for project Group:ProjectB:1.0-SNAPSHOT: The following artifacts could not be resolved: Group:ProjectA:jar:1.0-SNAPSHOT...
Now I can resolve this by doing a mvn install in the ProjectA directory - I've tested this and it does resolve the issue.
But my question is why should I have to? Shouldn't Maven figure out it should be installing the jar in the local repo?
Thanks in advance

TL;DR Tell maven about the structure of your project.
When you run the command
mvn -f pom.xml clean install
Then maven uses the reactor to work out the order of the modules, something like the following is output:
[INFO] Reactor build order:
[INFO] ProjectA
[INFO] ProjectB
So Maven first builds project A, then builds project B.
When you run the command:
mvn -f ProjectB/pom.xml clean install antrun:run
Then you have a problem; maven isn't starting from the parent - it's starting from a child. It's not told about the hierarchy of projects needed to be built first.
If you want to build a single project from a maven multimodule project, along with dependencies you should use:
mvn -f pom.xml -pl ProjectB -am install antrun:run
Where:
-pl ProjectB is the "project list" option, it tells maven to build these specific projects
-am is the "also make" option, it tells maven to build any projects that the projects in pl are dependant on

Specify the dependencies build part when you run the build:
Guide to Working with Multiple Modules

So I suppose the rule is, always build the parent project first and then run goals on subprojects afterwards.
The fix for me was to run clean install on the parent project first and then have a second build configuration in Jenkins that ran -f ProjectB/pom.xml antrun:run

Related

Maven enforcer issue when running from reactor level

Maven version used: 3.5.2, 3.5.3
mvn clean package -pl <root-artifact-id>:<module-name>
is failing saying
[WARNING] Rule 3: org.apache.maven.plugins.enforcer.ReactorModuleConvergence failed with message:
Module parents have been found which could not be found in the reactor.
module: <artifact:id>:<module-name>:war:1.0-SNAPSHOT
But working fine when running the mvn clean package from the module level though. Thats the only warning message in the trace causing the enforcer to fail the package build.
It's a very old reported bug but nobody seems to do anything about it: https://issues.apache.org/jira/browse/MENFORCER-189
Root cause would be that it compares the artifactid (module-name) of the project passed in the -pl paramater with the artifactid (reactor) of its parent. Which would never be the same and thus will always give this error.
For us the fix was to disable the enforcer plugin when using this execution (other executions without the -pl like 'clean install' are fine)
mvn clean install
mvn package -pl module-name -Denforcer.skip=true
Edit:
Another option is to specify the reactor project in the build using '.' (note: this will also package the reactor)
mnv clean package -pl .,module-name
Try including --also-make or -am, for example:
mvn -am -pl <root-artifact-id>:<module-name> clean package
Even if the module you're building doesn't have a dependency on another module within the build, this triggers a Reactor build that includes the given module and the parent POM together, and their relationship is then able to be verified by Enforcer without skipping. (Works with Maven 3.6.2 in my case).

Maven - parent project requires child plugin

I have forked a maven project (webservice) having a parent module and 3 child modules. One of the 3 modules is responsible for running the others and uses tomee plugin to run.
The documentation says: use mvn clean package tomee:run to run the web service.
If I run this command in the root directory, I get:
No plugin found for prefix 'tomee' in the current project and in the plugin groups
since the plugin is the child module pom.xml
And if I run the command in the child (runner) directory, I get:
Failure to find **Another child module war file** in https://repo.maven.apache.org/maven2 was cached in the local repository.
From where I should run the command, and how it fix it? I don't think the pom.xml files structure have bugs. But I don't know how to run a project with multi modules.
I used to run:
mvn clean install and mvn clean package
In the parent module directory, then in the 2 child (not the runner) and finally in the runner child module I run:
mvn clean install and mvn clean package tomee:run
And it works.
For the future, I only run
mvn clean package tomee:run
In the runner child directory to start my project.

Dependent maven projects compilation failure

I have a maven project that depends on another local maven project. For example Project A depends on ProjectB
Directory layout:
-TopDir
-DivergedDir
-someSubDir
-ProjectA pom.xml
-TopDir
-subDir2
-ProjectB pom.xml
In my Project A pom.xml I have:
<dependency>
<groupId>projectB</groupId>
<artifactId>projectB-artifact</artifactId>
<version>projectB-version</version>
</dependency>
When compiling project A I have to do the following:
1) go to project B directory and run mvn install && mvn compile
2) go to project A directory and run mvn compile
Is there a way I can run mvn compile in project A directly without have to go to directory of projectB first? As in reference Project B from Project A in a different way?

Running custom pom.xml in child module of Maven Project?

I have a java maven project which has 1 parent pom and 3 child modules associated with it. One of the child module has a custom pom.xml alongwith the default pom.xml.
If I run mvn clean install on Parent pom, all the 3 child modules (with default pom.xml) gets executed.
I wanted to run custom pom.xml instead of default pom.xml for one of the child module.
I tried below:
mvn -pl module1,module2/custom.xml,module3 clean install
But it didn't work and I got below error:
[ERROR] [ERROR] Could not find the selected project in the reactor:module2/custom.xml
Instead of having custom pom for one module, you can use maven profile to achieve custom behavior in some build.
You can run maven build with:
mvn -P profile_name clean install

maven dependency for multi-module project

I have a strange issue with maven.
I'm running a dropwizard project that has multiple modules.
Project
-> ServiceModule1
-> ServiceModule2
-> ModelsModule
-> TestModule
All modules depend on the test module, and all of the service modules depend on the models module.
I'm using a test-jar to distribute the test module since all of the fixtures live in there.
So when I package my project, I do this:
cd testModule
mvn jar:test-jar
cd ..
mvn package
This works fine, except it means every time I want to package my project I have to run all the tests. If I switch to
mvn package -Dmaven.test.skip=true
I get a failure because my modules start to look for their dependency jars in maven central.
This is really frustrating, since the tests depend in a database and I don't want to install a database on every web server.
What should the "correct" setup be?
Just to be clear, if your ServiceModule1 wants to depend on ModelsModule, you can build it in two steps,
$ cd ModelsModule
$ mvn clean install
$ cd ..
$ cd ServiceModule1
$ mvn clean package
Please note install in step2,
In other words, it is not mandatory that all your lib should be in maven central. But it is mandatory that all of them should be in your local repo. install is a goal which can install a lib to your local repo.
Now this link will show you how to install a test jar to your local repo.

Categories