Where does Super POM come from in the config - java

When I look at my effective pom in Eclipse, I can see a load of dependencies and a label stating that this is our corporate super pom which must form part of every project.
I can't actually work out where the super pom comes into play in the config. I have looked at my settings.xml in maven, and it has lists to remote repositories, and internal repositories - but can't seem to see a link to the super pom anywhere.
It is a muliple module maven project built from an internal archetype, and the parent module has a parent artefact defined...but when I browse the parent artefact, I still cant see how the super pom comes into play.
Any advice appreciated.
Regards
i

The super pom is defined by the <parent> tag:
<parent>
<groupId>com.mycompany</groupId>
<artifactId>mvn</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>

All pom implicitly inherit from super pom which is present in the maven distribution. This pom contains defaults for all maven projects which can be overriden in your maven project. But most of these defaults are not overridden as they typically form the convention part of maven as it is a build tool geared more towards convention. For e.g., the default build directory is target and hence this configuration is present in super pom as
........
<directory>${project.basedir}/target</directory>
.........
For more information and actual location of this pom please refer here and here

Related

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.

In maven, how can I refer to a parent pom that does not exist at that location on the file system?

I didn't realize this was possible to do, but apparently it is because this project I inherited does it. The project's pom looks like this:
<parent>
<groupId>my.group</groupId>
<artifactId>artifact</artifactId>
<relativePath>../parent/pom.xml</relativePath>
<version>1.0.14</version>
</parent>
That "../parent/pom.xml" does not exist on my file system, yet this project builds without issue. Even Intellij is confused and marks this relativePath in red.
I know this has something to do with the way my ~/.m2/settings.xml is configured, because the project did not build and complained about the missing pom.xml until I used the company's settings.xml. But I'm not sure where in that file it is making this work.
Can someone point me to some documentation that describes how this feature works? We are using the Nexus maven repository.
When Maven goes looking for the parent POM, it first looks in the place specified by <relativePath/> (which is ../pom.xml by default); if it cannot be found there, it goes and looks in your local repository (~/.m2) and then tries to download it from the remote repository.
Without seeing your settings.xml it is impossible for me to be sure but my best guess is you have a remote repository listed there that made it possible for maven to perform that last step - download the parent POM from a remote repository that is defined in settings.xml.
Reference: https://maven.apache.org/pom.html#Inheritance - "Notice the relativePath element. It is not required, but may be used as a signifier to Maven to first search the path given for this project's parent, before searching the local and then remote repositories."

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

How to inherit External Maven POM in Project POM

I'm looking at the Google Web Toolkit pom file at http://gwt-maven.googlecode.com/svn/docs/maven-googlewebtoolkit2-plugin/examples.html and it doesn't seem right to copy all of it into my project pom, as it would add too much unnecessary clutter.
Hence, am looking for a way I could store the GWT pom in an external file, and make reference to it in my project pom.
Anyone knows?
That project is deprecated, use gwt-maven-plugin from codehaus.
Hence, am looking for a way I could store the GWT pom in an external
file, and make reference to it in my project pom.
That's multi-module-project setup, have a look.
Have you tried using the gwt Pom as the parent Pom for your project?
Something like this in your pom.xml?
<parent>
<groupId>com.totsp.gwt</groupId>
<artifactId>maven-gwt-sample-withouthome</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>

Categories