Maven - skip parent project build - maven

I know it's mauvais ton to ask twice in a single day but here's another Maven puzzler:
I have a parent POM which defines 5 modules (5 subprojects). Since each module is executed in exactly the same way I pull <profile><build> section into the parent POM to get rid of the duplicate code. Now - if I execute build individually from each module it works, however if I want to build all modules at once and move to the parent directory I got error since the very first thing Maven tries to execute is the parent project itself:
mvn package -P release
[INFO] Scanning for projects...
[INFO] Reactor build order:
[INFO] DWD Parent project
[INFO] Projects
After that build fails because exec plugin tries to execute something that is not there. Looking at the output it is pretty obvious that reactor plugin is driving the build but how can I configure reactor to skip the parent?
P.S. To prevent confusion - I'm trying to suppress profile execution on parent and enable it on child during the same build

You can't skip the parent build, but you can configure the profile to not be activated with a little hack. This answer shows how to control the activation of a profile by the presence or absence of a file-based <activation> element. This way you can define the profile in the parent, but have it deactivated in that project because of the marker file being present in the parent. Child projects would not have the marker file in their source, so the profile would be activated for those projects.
Update to clarify: On my test project this configuration means the profile is deactivated in the parent project (which has the file in src/main/resources), but activated in all child projects which do not have the file in their resources directories.
<profile>
<id>test</id>
<activation>
<file>
<missing>src/main/resources/test.marker</missing>
</file>
</activation>
...
</profile>

What is wrong by building the parent?
In fact, in Maven, there are two different concepts (which are generally used at the same time):
The parent POM
The modules aggregation
The first one is a definition of everything that is common with all the children. You define a parent as a pom-packaged project, and you can install it in your repository.
When you build a child of this parent, Maven2 will retrieve this parent to merge the parent pom with the child pom. You can have a look to the entire pom.xml by running the command mvn help:effective-pom.
In this case, the parent pom will not be built, it will just be retrieved from the repository.
The second case is a project that contains a modules list of sub-projects. The principle is that every command that you run on this project will also be run on all the sub-modules. The order of the modules will be defined by the Reactor, which will look at inter-modules dependencies to find which module must be built before the others. If there are no dependencies, then it will take the list of the modules as they are defined in the parent pom.xml.
In this case, if you run a command on the root project, Maven2 will first built the root project, and then the sub-modules. You cannot skip the creation of the root project.
Edit, thanks to RichSeller comment
A complete explanation of the differences between multi-modules (aggregation project) and inheritance (parent project) can be found in the Maven book, here.

I want to document that there's partial compromise to my situation (thanks to guys on maven users mailing list for suggestion). Basically you need to chop profile in two pieces. Reusable configuration section of plugin goes to the parent POM, and executions stays in the child POM. Then the profile plugin in the child is marked as inherited and voila - at run time parent profile is not executed since it's missing executions section. This is far from ideal but it does work. Refer to this link for example

I wasn't able to implement "missing" file solution as provided by Rick Seller above. It seems that once set active/non-active state of profile will not be changed even the marker file is missing from the module(s). However here's the exact solution to my problem. Warning: this is only available starting with Maven 2.1+
If I have a parent POM with 2 modules defined: foo and boo then in regular circumstances order of execution will be:
parent
foo
boo
All I need to do to skip parent build is to add this command line switch
mvn install –rf foo
Alternatively you can use --resume-from What it will do is to skip parent and continue from foo module down. Now - I'm investigating if this can be achieved by configuring Reactor plugin (P.S. - no it can't) but even with the switch, the above scenario works fine for me

This is implied by #romaintaz's answer to the same question, Maven - skip parent project build
but just to make this explicit, in the parent pom it's imperative that you specify the packaging element as pom (and not jar or war).
Example:
<packaging>pom</packaging>

Related

How to run maven plugin for only root of multimodule project [duplicate]

I have maven multi-modules project. At the parent level, i have some java files. And in the parent pom.xml, at the package phase i do some stuff.
Usually, when i run mvn package at parent level, the package phase of parent pom will be run and all the modules will be packaged as well.
I am looking for a way that allow me to do these (when i run mvn package):
allow me to run only paren pom.xml (the script at the package phase), not the modules. This is the 1st priority.
allow me to run paren pom.xml and some particular modules (like module 1, module 2 BUT not module 3 , module 4).
Can i use profile for those issue?
Thanks.
While I agree with the fact that you may not have optimal project structure, the answer is that Maven 2.2.1 has an option "--non-recursive" which satisfies your first requirement:
-N,--non-recursive Do not recurse into sub-projects
So something like this:
mvn --non-recursive clean compile
Why do you want to have java code on the top level? In my opinion this is not a very good idea. Have your code in the subprojects and let the top-level project be responsible for holding the general information and configuration of the entire project.
If you have some base-library code in the top-level project now, you can put it in a sub-project and set up dependencies between the projects.
Take a look at Maven parent pom vs modules pom
The nature of your question indicates that your project structure may not be optimal.

What are the difference between pom.xml and effective pom in Apache Maven?

Could somebody explain to me, what are are differences between the file pom.xml and the file effective pom.xml in an apache maven project?
The Super POM
All Maven project POMs extend the Super POM, which defines a set of defaults shared by all projects.
The Simplest POM
All Maven POMs inherit defaults from the Super POM. If you are just writing a simple project that produces a JAR from some source in src/main/java, want to run your JUnit tests in src/test/java, and want to build a project site using mvn site, you don’t have to customize anything. All you would need, in this case, is the simplest possible POM shown in The Simplest POM. This POM defines a groupId, artifactId, and version: the three required coordinates for every project.
The Effective POM
It is the merge between The Super POM and the POM from The Simplest POM.
NOTE: This info was extracted from the following link (in the link the explanation is very complete)
Maven: The Complete Reference - 3.2. The POM
You can see the difference of a pom.xml and the effective pom.xml using
mvn help:effective-pom
which is describe here.
In a multi module project you'll use a parent pom.xml for defining general settings for all modules and then in each module there will only be specific settings.
The above goal will help you analyze the resulting pom that you could of course actually use instead of the parent reference.
The whole idea is by using the generalization (super-pom) / specialization (module pom) approach there is a central place where you can specify the general configuration. This is much more efficient then having to cut&paste the general parts.
Please also note that the effective pom will add the default behavior e.g. for the jar plugin so that you can debug issues like
Maven JAR Plugin 3.0.2 Error: You have to use a classifier to attach supplemental artifacts to the project instead of replacing them
with this approach. See also Maven `help:effective-pom` only generating for a single project, not all projects

Can Maven automatically build a dependency that is not found?

I have three separate projects I am working on (A, B, and C).
Project B and C rely on a jar that project A generates.
Does Maven have the ability to automatically build project A if the dependency is not found?
The answers I've found so far are indicative of making the other 2 projects modules (which I believe to mean repository layout and incorporate them into project A) and create a parent / child pom.
A just plain "no" was also one of my conclusions as well.
It seems as though if I make a module of project A in B and C, maven doesn't really like that. Can Maven see projects during build time that are outside of the scope of the current project? Sorry if that's a little wordy.
The scenario works fine if A, B and C are modules of a common container project.
From root pom.xml:
<modules>
<module>project-a</module>
<module>project-b</module>
<module>project-c</module>
</modules>
where "project-a" etc. are names of maven project folders inside the parent folder.
The parent project must have <packaging>pom</packaging> for this to work.
Then you can build the parent project and it will build all children in order, or you can use one of the advanced Maven reactor flags.
e.g. mvn clean install -pl project-b will only build project B.
For more info, execute mvn --help and read the multi modules chapter from the Maven By Example book.
But to this question:
Does Maven have the ability to automatically build project A if the
dependency is not found?
... the answer is always no. Maven fails if the dependency is not found, but it never decides which projects to build. You are in charge of which projects need building.

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