Parent POM dependency tree discovery for sub modules (Maven) - java

I have created a maven goal that outputs a dependency tree for a given maven project to a YAML file. Using the m2eclipse plugin for Eclipse Photon.
Currently when I run the goal against a parent project (using type pom when setting up dependency), the only dependency returned is on the pom for the specific parent. Is there any way to prevent me needing to run this goal against all of the projects underneath the parent?

Might need a little more information on this, but are your children poms of the parent specified as modules within the parent pom?
Example:
<parentPom>
<modules>
<module>/path/to/childA</module>
</modules>
</parentPom>

Related

There is a way to execute just a Maven subproject?

I am wondering if there is a way to run a Maven subproject alone. I mean, in several code samples you can find a group of maven projects with a common parent. There is a way to replace parent in order to be able to run just a subproject.
Lets suppose this repository https://github.com/in28minutes/spring-boot-examples
There is way to run just spring-boot-tutorial-soap-web-services/ project?
Thanks in advance.
maven projects are identified by pom.xml and you can run any maven project individually. (Any maven goal).
cd into_a_maven_project(identified by pom.xml).
mvn install(this will run install phase for the project).
There are several relationships among maven projects.
Parent-child
Submodule
Dependency
Parent-child: This relationship is used in defining a pom. For instance, When a set of pom shares a lot, you can define a parent pom(parent maven project) and reference from the child project. (reference is done from child to parent)
When you run child project, the parent project is used only to inherit the pom(copy the content of parent pom). Child pom overrides the configuration in parent pom.(child pom contains little because of the fact that required configurations copied from the parent pom)
Submodule: This relationship is used when it makes sense to build multiple projects together. In this case, you run build in the project referencing submodules. (This is not a parent child relationships, the pom is not inherited if the project is not also a parent). The result is that the submodule projects become part of the build. (The order of the build is determined by dependencies between them)
Dependency: This relationship is used when the code in a project depended by your project. The build order is calculated using this relationship.

Execute maven plugin in children, not grandchildren or parent

I have a maven Mojo plugin that I'd like to execute only in child pom, but not in the current pom or grandchildren poms. My plugin runs at compile time and essentially reads files, and for my use case if it runs in the child pom, it is redundant to run in grandchildren poms.
For example, I have a maven Mojo plugin that gets called by a parent pom file ParentFile. This pom file is inherited in other repositories, which I don't have write access to. In these repositories, there is a root module with a pom file ChildFile, whose parent is ParentFile. There are also other submodules in the repository that contain pom files (GrandchildrenFiles) whose parent is ChildFile.
I would like to execute my Mojo plugin from ChildFile, but not from GrandchildrenFiles or ParentFile. Is there a way for me to do this without write access to the repositories containing ChildFile and GrandchildrenFiles?
You probably cannot stop your plugin from being executed, but you could check, as first step in your plugin, if your parent is the parent you expected. For that, you can use project.getParent().
If not, you just skip the rest of the execution.

Maven Modules with Variable as Version number

I got a Maven project with the following structure:
Module A (parent), Submodule B and Submodule C
In the parent pom.xml I am using a variable for settings the version of all projects:
...
<version>${revision}</version>
...
<properties>
<revision>1.1</revision>
</properties>
...
<modules>
<module>moduleB</module>
<module>moduleC</module>
</modules>
</project>
Module C is my distribution package which uses the shade plugin for packaging everything into one single jar.
In the submodules I set the parent like this:
<parent>
<groupId>group</groupId>
<artifactId>moduleA</artifactId>
<version>${revision}</version>
</parent>
Now I want to use Module C in another project, however I only get the following error when doing so:
Failed to execute goal on project newProject: Could not resolve dependencies for project group:newProject:jar:0.0.1-SNAPSHOT: Failed to collect dependencies at group:moduleC:jar:1.1: Failed to read artifact descriptor for group:moduleC:jar:1.1: Could not find artifact group:parent:pom:${revision} in nexus (NEXUS_URL)
I assume the problem is, that the variable value is not filled in when referencing Module C as dependency. How can I solve this issue? I already tried to clean the project before building and forcing to update all artifacts without success.
Maven expects all modules to have a hard version.
To avoid editing lots of poms, use the versions plugin, example:
mvn versions:set -DnewVersion=1.0.1
If you run the above command on the parent it will fix all the child poms.
See here for documentation.
Thanks to the comment of hadu.mansouri I could fix it. I used flatten-maven-plugin for flattening the pom.xml files. However, it seems to have a problem with the shade plugin, as the shaded module was the only module where it did not work. Thus, in the released shade module pom it said:
<version>${revision}</version>
for referencing the parent. I used the approach of the article linked in the comment. There, this extension was used: https://github.com/jcgay/unique-revision-maven-filtering
Using this instead of the flatten-maven-plugin, Maven builds the multi module project correctly with the single version property, and I can also use the shaded module in other projects properly.

How to deploy a maven parent module with flat module hierarchy?

I have 3 maven modules. One is the parent grouping the other 2 modules.
All project folders are on the same root level.
Though the deployment is not working. What's wrong with the following configuration?
project-parent/pom.xml
project-commons/pom.xml
project-web/pom.xml
parent-pom:
<project>
<groupId>de.myproject</groupId>
<artifactId>project-parent</artifactId>
<packaging>pom</packaging>
<modules>
<!-- <module>../project-commons</module> -->
<module>../project-web</module>
</modules>
</project>
web-pom:
<parent>
<groupId>de.myproject</groupId>
<artifactId>project-parent</artifactId>
<version>1.0.0</version>
<relativePath>../project-parent/pom.xml</relativePath>
</parent>
Result:
[ERROR] The project de.myproject:project-parent:1.0.0 has 1 error
[ERROR] Child module \project-parent\..\project-web\pom.xml of \project-parent\pom.xml does not exist
The project structure:
svn/project-commons/trunk/pom.xml
svn/project-web/trunk/pom.xml
svn/project-parent/pom.xml
I will outline an approach that I have used successfully on large and small projects that may meet your needs.
pom.xml
superpom/pom.xml
utils0/pom.xml
utils1/pom.xml
utils2/pom.xml
services0/pom.xml
services1/pom.xml
services2/pom.xml
war0/pom.xml
war1/pom.xml
In this example, the utils and services modules produce jars; the war modules produce wars. There would be various dependencies between the utils, services and wars.
The superpom modules is of type pom and just contains the parent pom. Each of the util/service/war pom.xml refer to the parent with the relative path of ../superpom:
<parent>
<groupId>mygroup</groupId>
<artifactId>superpom</artifactId>
<version>1.3.3.3-SNAPSHOT</version>
<relativePath>../superpom</relativePath>
</parent>
The superpom/pom.xml does NOT contain any elements and does not refer to the "child" modules/poms in any way. The superpom contains shared properties, plugin configs, dependency versions, etc. It is a big pom. All the other module's poms are (generally) small.
The top-level pom contains the references to all the other modules (including superpom). It does not have a parent pom (at least not one that lives within this project hierarchy). You use the top-level (not superpom) to build everything. You can use profiles (or other means) to control which modules you want to build, but I have generally just built the whole tree from here. Support for SCM, CI builds, etc. lives in this top-level pom, which keeps all your other projects (including the parent pom) clean and concerned only with building and testing the artifacts.
I don't have any concept of "trunk" in my maven structure - that is an orthogonal concept. If I want to work on trunk or a branch, I check out the appropriate one and always have the same maven structure.

How to remove dependency: maven sub-modules creates implicit dependency on parent module

I have a maven project
Parent Project (with the following modules) (package type pom)
API Project (package type jar)
Packaging Project (has a dependency on API Project) (package type custom)
I want to be able to deploy the API project to Nexus repositories so others can leverage that code. The Packaging Project is more of a supporting utility project for a smaller set of deployment use-cases. The Parent Project wraps it all together for me.
When I deploy the API project to the nexus repo, it deploys fine. If i try to make a brand new project that has a depdency on API, it finds the API dependency in nexus but then also wants the Parent project as well. Is there any way to get around publishing the parent project as its really isnt necessary for use of the API lib when used via the nexus repo?
Any tips on how to organize my maven proj to support this?
When you add a <parent> reference to a Maven project what you are doing is saying: "Take all the configuration from that parent and inject it into my model, then override with the following"
Therefore, in order for Maven to build the model of your project, it is necessary for Maven to retrieve the parent itself. In other words, adding a <parent> tag creates an explicit hard dependency between the parent and the child.
The good news is that Inheritance does not have to follow Aggregation. What does that exactly mean?
Aggregation is when you list <modules> in your pom. It tells Maven that the reactor (i.e. the set of projects that Maven builds) should also include the following (sub)projects.
Inheritance is when you set a project's <parent>.
Nowhere does Maven enforce that a project's <parent> has to list its children as <modules> and nowhere does Maven enforce that a projects <modules> must list the project as a <parent>.
Some people will set up their project like so
ROOT/
+- pom.xml
+- parent/
| \- pom.xml
+- api/
| \- pom.xml
\- packaging/
\- pom.xml
where the parent of ROOT, api and packaging is actually a child of ROOT. Or sometimes ROOT will be a standalone project with no parent [In fact this is a pattern I use a lot myself. When I am working on several related project I will throw together an aggregating pom.xml on my local disk and open that with my IDE and that way all the related code is available as one single "project", even though the actual modules may come from different sources]
So in your case the solution would be to remove the <parent> tag from your "API" module.
Now! There is a downside. When you remove the <parent> tag from your "API" module you have removed all the defaults that your parent project is providing, so you will need to copy those defaults that are relevant to the "API" project or else you may find subtle changes in behaviour. For example, you should definately copy over the pinning of plugin versions, and any <dependencyManagement> that is relevant to the "API" dependencies. There are other bits you may have to copy, but you should use the Maven command mvn help:effective-pom before and after removing the <parent> tag as an aid to seeing the effective differences
for my developments I use uber-pom maven plugin which merges information in maven project hierarchy and provides independent pom as result and I publish artifacts in maven central without any extra links to parents

Categories