Maven multi module project build: modules in local repo - maven

Suppose we have a multimodule project:
<modules>
<module>first</module>
<module>second</module>
</modules>
where second depends on first through dependencies.
If I run mvn cleanpackage, does maven or reactor will put any of the modules to local repo anyway?

The answer is no.
Here are the maven lifecycle phases
As you can see, package comes before install, so install wont be executed - nothing will go to your local repo, unless it was there already.

Related

Jenkins pipeline - maven installing dependency projects

I am setting up a CI/CD with the following components:
-Bitbucket
-Jenkins
-Docker
-Maven
The desired flow:
Committing code to Bitbucket
Webhook Jenkins on changes
Jenkins pipeline does the following:
mvn install 2 projects, SDK+API
takes the API jar and build image
pushes image to repository
deploys service or container to docker
Where I am currently stuck is the following:
I have a PROJECT-A, that has multiple dependency projects that has to be maven installed, before maven installing PROJECT-A and creating an image of it.
Could anybody advise on what is the best practice here?
I have googled an it's say that my only feasible and maintainable option should be using Parent POM. However I failed to understand how do I do that.
<modules>
<module>project1</module>
<module>project2</module>
<module>project3</module>
</modules>
Even if your project would be structured differently with parent pom, where would those additional projects come from? In general mvn install does something different then you mean in this question -
install: install the package into the local repository, for use as a dependency in other projects locally
The best practice here (and missing element) is a package repository. For example your private artifactory or nexus. You would mvn install all the packages to it and maven would automatically resolve the dependencies from it basing on its POM and appropriate configuration.

Maven - do a mvn install on local artifact when packaging

i have a maven project which has some local artifacts as dependencies.
When I have to package my main application, i have to do a mvn install command on my local repositories before, which is quite annoying and easy to forget.
Is there a way to tell maven to install local repositories when packaging the main one?
One solution can be to wrap up all your components into a pom project.
When building a parent pom maven automatically triggers a build of all the sub-modules.

In maven multimodule project is it recommended to use package or install

I have a maven multimodule project
<modules>
<module>A</module>
<module>B</module>
<module>C</module>
</modules>
Module C depends on Module A. In this project structure can you let me know it is recommended to use package or install. I do not have any other requirement to share this project with other projects.
When launching a Maven command on multiple modules, if a dependency specified in one module is available as a project being built in the same command, Maven will use the output of the current build as dependency, instead of the JAR present in the local repository.
So it is not necessary to use install to make the changes of a module available to modules depending on it, as long as these modules are always built together.

Independently building Maven submodules

After being introduced to Maven in my most recent project, I've been experimenting with it for the past couple of weeks.
I currently have a multi-module project in my development environment. Project "A" and Project "B" are child modules of Project "root", with B having a dependency on A.
I am aware that I can build B independently by using mvn reactor:make... as outlined here. However, I'm curious as to why am I not allowed to build B from inside B's root folder.
To illustrate this, I first built A independently by running a clean install from within A's root directory. However, when I tried doing the same action from B's root directory, Maven reported an error as below -
Could not find artifact org.divesh.mavenrnd:root:pom:1.0 in central
It looks like Maven is not able to resolve the parent's POM file. Any thoughts on why this is happening? From my initial understanding of Maven multi-module projects, the main reason to split a project into sub modules is to share dependencies. This should not, however, prevent me from building a particular module independently from within its folder.
Thanks.
EDIT
Ran an mvn -N clean install to install only the root project's POM in the rep. After this, I was able to successfully build B after building and installing A. There is still one thing I'm not quite clear about -
Assuming I've installed the root project's POM in the repository, if I try to build A, does it refer to the parent root POM directly above it or the POM that is installed in the repository?
That's right. The error you mentioned tells you that maven cannot find parent's pom.
You have 2 options here:
First call mvn -N install in your root project directory to install parent pom to your local repository. Then you can go to B's directory and build the submodule.
Specify <relativePath> in your submodule pom. By default maven will look for parent pom only one level up the file system. If you have other directory structure in your project, you have to specify this option in order for maven to locate your parent pom.
Here's a sample:
<parent>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<relativePath>../../pom.xml</relativePath>
</parent>
You should use mvn -pl ProjectToBuild lifecycle like from the root of your tree:
mvn -pl module-b package
You shouldn't use mvn reactor:make anymore. Except you are using maven 2.0
If you wan't to be sure that everything is depending on module-b is build as well you should use:
mvn -amd -pl module -b package
The best is having a folder layout which represents the appropriate structure of your project and not using relativePath is necessary.

How can a maven project depend on another local maven project?

I'm having two maven project project/foo/pom.xml and project/bar/pom.xml. I have foo depend on bar, and I want that every timefoo/pom.xmlcompiles, it'll automatically compilebar`.
How can I do that with maven?
Update: I can tuck them both into a parent project, but then, what will I do if I want to run mvn jetty:run on a child project?
Option 1
Setup both builds in Jenkins, which can detect dependencies between projects
Automatic build chaining from module dependencies
Jenkins reads dependencies of your project from your POM, and if they are also built on
Jenkins, triggers are set up in such a way that a new build in one of those dependencies
will automatically start a new build of your project.
Option 2
If the two Maven projects are closely related (released together, sharing the same revision number) then perhaps they're really two modules of the same project?
If that is the case read the following document for guidelines on how to create a parent POM:
http://maven.apache.org/guides/introduction/introduction-to-the-pom.html
You can combine them into one project, with two modules.
An example project structure:
parent (pom)
|- foo (jar)
|- bar (jar)
In the parent pom:
<groupId>org.me</groupId>
<artifactId>parent-project</artifactId>
<packaging>pom</packaging>
<modules>
<module>foo</module>
<module>bar</module>
</modules>
In each child pom:
<artifactId>foo</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>org.me</groupId>
<artifactId>parent-project</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
To build the project (both modules) with Maven, execute this from the parent directory:
$ mvn install
This is not possible using maven alone. The closest you can get is to make both as modules of an aggregator POM, so you can build both with a single command. Note that a mvn install will already consider if there have been changes since the last build so you're saving a few CPU cycles there.
First, setup a multi-module build as Daniel has shown. Then change to the directory with the parent POM. Then, for example to install foo with automatically installing bar before, too, type:
mvn --also-make --projects foo install
This will check the dependencies within the reactor and then resolve to run the install life cycle on bar before it runs the install life cycle on foo.
This works with any life cycle or goal. Mind you however that if you specify jetty:run, then this goal would be run in both projects, which is probably not quite what you want.
You can find more information about this feature here: http://maven.apache.org/guides/mini/guide-multiple-modules.html

Resources