Which Pom is parent? - maven

In a maven project which pom.xml is the parent pom? And is that the one I need to change in order to add a profile?
I have a simple project and am trying to add a profile to download from a specific repository but nothing's seems to be working.

I assume you have a multi-module build.
Parent relationship is optional between poms, and specified with the <parent> tag inside the pom.
You may point to a single pom, but if not, you point to a default super-pom.
Use mvn help:effective-pom to shed some light on your settings.
If you have a shared pom file, you can add profiles to that one, otherwise you need to include them in each pom.
Use mvn help:active-profiles to see which ones are enabled.
For ref: http://maven.apache.org/guides/introduction/introduction-to-profiles.html

Related

In maven, can I define a variable used in another pom?

I'm getting an error when running maven build (unable to load a dependency).
[ERROR] Failed to execute goal on . . .
Could not transfer artifact my.group:libme1:${someVariable} from/to . . .
I believe that the developer that published this artifact was supposed to be setting the variable ${someVariable} but didn't. I think this is a bug but I'm trying to work around it by setting the variable.
The POM for the JAR I'm depending on my.group:libme1:1.2.3 looks like this (snippet highlighting the issue):
<groupId>my.group</groupId>
<artifactId>libme1</artifactId>
<parent>
<groupId>my.group</groupId>
<artifactId>libme1-parent</artifactId>
<version>${someVariable}</version>
</parent>
I tried defining it by adding -DsomeVariable=1.2.3 on the command line but it didn't work. For example, this command
mvn -DsomeVariable=1.2.3 clean install
should work based on Baeldung's article but doesn't.
I also ran:
mvn -DsomeVariable=1.2.3 help:effective-pom
and I see the variable being set, so I know he POM I'm using has that defined, but for some reason another POM doesn't pick up that value (or that is how it appears to me).
Is there any way to set the variable so it can be used in another POM? I'm guessing this is not possible.
Searching for an answer I found:
The maven doc
https://maven.apache.org/settings.html#Activation
If you know that this is bug, please let me know. I'm also reaching out to the publish of the artifact to ask them how this is supposed to work.
Basically the dependency's pom is invalid, the reasoning is following:
maven allows developers to do following things:
define dependencies in parent pom
impose restrictions on dependencies via <dependencyManagement> in both current and parent pom
use placeholders ${...} in <version> element, which somehow get resolved via system properties and current/parent pom properties
all those features mentioned above are very convenient from development perspective, however when you publish artifacts those features cause a pain in behind: that became not possible to use external library without it's parent pom, because parent pom may define dependencies and properties.
In your particular case someone have define version of parent pom as ${someVariable}, that in turn means it is not possible to use that library without information about the value of ${someVariable}. However, even if you had known the "correct" value of ${someVariable} and might specify it via system properties, that would cause some weird behaviour: today you may specify one value for ${someVariable}, tomorrow you (or someone else) will specify another value and ultimately you will get different builds, due to that maven denies such configurations (that is much better to fail a build rather than build something unreliable), that would be wiser to initially deny publishing such poms, but we have what we have.
It might be that the variable was stored in some user's settings.xml.
This would allow checking out an older version already in production for writing patches.
<settings>
...
<profiles>
<profile>
<id>work-in-progress</id>
<properties>
<someVariable>1.2.3</someVariable>
</properties>
</profile>
</profiles>
<activeProfiles>
<activeProfile>work-in-progress</activeProfile>
</activeProfiles>
</settings>
So you might do that too. And search in users' directories, .m2 repo directories where usually the settings.xml is stored.

Have maven list (transitively) inherited parent POMs?

Is there an easy way to make maven list the parent POMs a POM inherits directly and indirectly?
I'm looking for something similar to
mvn dependency:tree
only "upstream" (i.e. for parent POMs inherited), not "downstream" (i.e. for dependencies on other libraries)...
I wanted to print the version of our corporate parent POMs. I used the GMaven plugin for this, as described in this stackoverflow answer. You could modify that code bit to print each parent POM.
I don't know a Maven command to do this. If you use Eclipse and the m2e plugin, then you can press F3 inside of the <parent> element to visit the parent POM. Then rinse and repeat.

maven skip/ignore parent tag

I wonder if it is possible to ignore parent tag in the pom.xml file. I need this because I have the following situation:
the structure is:
super root pom
root pom
module1 pom
module2 pom
module2.1 pom
module2.2 pom
module2.3 pom
I need to set super root pom as parent pom for root pom to make it availible to build it specifically on build server, but the trick is, that I don't have super root pom locally and need to ignore parent tag or do something not to be dependent on super parent pom. So, for example, I need to run root pom clean install independently from the super root pom. Is there any way to do this using some parameters or some pom.xml tricks?
Thanks everyone in advance!
If you have a corporate repo (Nexus, Artifactory...) The simpler would be to mvn deploy your parent, to make it available for all your projects, all your team, with no need of a local (relative file system path) relationship.

How do I get my parent pom to output tar.gz files

I have a parent pom and children pon and when I run the mvn clean package on the parent pom I am getting .jar file, is there anyway to change this to tar.gz file? For the children files I have created assembly.xml files to specify tar.gz file do I need to do the same for parent pom?
Specify POM packaging:
<packaging>pom</packaging>
I'm a little surprised that your parent POM is working without that setting. I've received errors from Maven before when I create a new parent POM and forget to change the packaging from jar (default) to POM.
The parent is not really meant to produce artifacts other tan the pom.
You could try attaching the assembly plugin to a phase such as process-resources or something and try to have it package whatever resources you have in mind, but... generally, it's not a good idea to keep resources in your parent.
If the projects that extend this parent do not define <packaging/>, their packaging will default to pom.

Maven: Selecting Parent Project Based On Profile

I have a maven project - it is a plugin for jenkins. It's parent should be a:
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>1.414</version>
</parent>
But at the same time this plugin can be also used for hudson, without changing any line of code. But the parent project for it should be:
<parent>
<groupId>org.jvnet.hudson.plugins</groupId>
<artifactId>hudson-plugin-parent</artifactId>
<version>2.0.1</version>
</parent>
Can I specify 2 different profiles for that and use them to build plugin for jenkins or hudson accordingly? So that I call something like that:
mvn package -P jenkins
or
mvn package -P hudson
I have tried to specify properties in profiles, but those are not replaced by their values inside the <parent> tag. So is there any other possibility to build plugin for both, but with as much as possible common code and files?
Added: So, if I cannot do that, what should I do then? How to refactor? What the new structure should be?
As already mentioned, this is not possible.
Also, it is not possible to set a property for the parent's version as the interpolation for that happens a lot earlier than the handling of the profiles.
I would suggest that you create a masterbuild project as follows:
master
|-plugin-jenkins
|-plugin-hudson
|-plugin-assembly
The master should build all three as usual. However, in the assembly, you could add each of the two plugins as dependencies in separate profiles. And... each of these plugins can have the parent you like.
This is obviously somewhat a deviation from the Maven convention, but I believe it is a solution to your problem.
It's not possible because the tag "parent" is not available in the profiles section of the pom.
Currently we decided to stick with 1 repository and 2 separate pom.xml files, giving maven key which pom.xml use to build the project.
mvn package -f pom-jenkins.xml
mvn package -f pom-hudson.xml
No you cannot do that. you will have to refactor somehow to avoid the necessity.
As mentioned already not possible. I would suggest to make separate projects for jenkins plugin and hudson plugin. I assume that in not that far future that will not work anymore cause Hudons and Jenkins will diverge.
In general, you should be able to set the {group,artifact}Id and version of the parent POM via Java System Properties or Environment Variables, but it seems there is a Bug in Maven which will only be fixed in 4.x:
https://issues.apache.org/jira/browse/MNG-624
Another solution is to delegate the inclusion of the parent POM to your own parent POMs which you reference in the relativePath element, and change the content of the target e.g. via a symlink or cp command.
So in the main POM you would write:
<parent>
<groupId>org.mycompany.project</groupId>
<artifactId>foo-artifact</artifactId>
<version>1.0.0</version>
<relativePath>./my-parent.pom</relativePath>
</parent>
And in my-parent-jenkins you would just put:
<groupId>org.mycompany.project</groupId>
<artifactId>foo-artifact</artifactId>
<version>1.0.0</version>
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>1.414</version>
</parent>
The same project information with the block for hudson you put in my-parent-hudson.pom.
No you can either use
ln -s my-parent-jenkins.pom my-parent.pom
or
ln -s my-parent-hudson.pom my-parent.pom
to include the respective parent POM without the need to maintain two different main POM files for your project.
In case POM does not exist at the place referenced in relativePath, Maven will look up the POM in the remote repository[1], which is also an easy way to overwrite a parent POM locally.
[1] http://maven.apache.org/components/ref/3.3.9/maven-model/maven.html#class_parent

Resources