Maven enforcer issue when running from reactor level - java

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).

Related

Maven test for only provided package

I have a multi-module maven project. I want to test only one package but that package may depend on other packages.
For better explanation, I created an example GitHub repository:
GitHub Example Repository
Running mvn -pl module test can cause problem because of dependencies of module. Instead of that, I must run mvn -pl module -am test but this command run test for my module and all dependents modules (in my example, run test for dependent-module-1 and dependent-module-2).
Performance is crucial for me. I don't want to run test for dependents package when I want to run tests for only one module. So I decide to convert my command to:
mvn clean
mvn -pl module -am compile test-compile (or mvn -pl module -am package)
mvn -pl module test
It doesn't works and give errors because of not provided artifact.
I search a lot and I don't find anything. Please consider that I don't want to use mvn install at all. I don't want to move it to my repository.
Is it possible to help me? I don't know what to do.
Thanks.

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.

Why Maven doesn't install dependencies in multimodule project?

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

difference between mvn clean and install commands

I am using maven for the build purpose and normally we use the maven command mvn clean -Dmaven.test.skip=true package only to build the web application. I know we can use the mvn install command also to build a web application. But can anyone provide me with the exact difference between these two commands?
I found some notes on the clean and install commands. But i just want to know what's the advantage of using mvn clean command instead of using install command.
The main different between mvn clean -Dmaven.test.skip=true package and mvn install is that the first command line cleans the target directory and packages without running the tests. The second one compiles, tests, packages and installs the JAR or WAR file into the local repository at ~/.m2/repository.
Maven has this concept of Maven Phases. Please go through the Maven Phases of this doc. So when you run a phase (say maven phase x) all the phases up to that phase is executed (that is phase 1 to phase x).
You need mvn clean to clean up artifacts created by prior builds. mvn package will package your code into your specified format in your POM. mvn install will also install the package made by Maven into the local repository.
Also note that clean and site are not part of phases of the default life-cycle. You have to fire it before your package or install command. Needless to say ordering does matter here.
As explained here.
clean is its own action in Maven. mvn clean install tell Maven to do the clean action in each module before running the install action for each module.
What this does is clear any compiled files you have, making sure that you're really compiling each module from scratch.

Testing Java project with many modules

I have a Maven Java project with many modules and one meta-modul. And I want to run test. I use: mvn test command in console. But my test fails when compilation, because classes in other modules are not found. But in IDE Eclipse no errors. How can I fix that?
if you have well defined dependencies, use mvn install instead of mvn test. Running tests is included in install phase too and you'll get the modules you need for compilation into local maven repository.
Try to run mvn install. This compile, packages and runs tests. Then when everything is compiled you can probably run mvn test only. But you should not (IMHO) because only when you are running the full process you are sure that the newest versions of your classes are being tested. Do not worry about efficiency: maven does not compile classes if it already have them compiled. Only mvn clean install will rebuild everything from scratch.
Your models need to be free of dependency cycles!
Try to run mvn test from the folder where the parent pom is located.
(details)
If you do not have a parent pom with sub modules. Then you must first run mvn install for all the other of your modules where the module you want to test depends from.
(Eclipse does not need this, because it can resolve dependencies to other open projects directly)
But if all the modules belong to an single release cycle (all the modules will be released togeter with the same version) then it is may a better approach to use parent and child modules/pom -- because then you can run mvn test or mvn install for the parent pom, and maven will do it for all the childs in the right order. -- After you have installed all other modules, you can run mvn test on a single module until you update an other modul. -- Then you will need to install this updated modul too, or better run install for the parent.

Categories