Maven use parent variable inside child version - maven

my issue is that I'm trying to use a variable which is defined inside the parent pom to use it as the version number for the child pom. The only thing special here is that the variable is defined inside a profile of the parent. But when the project deploys to the nexus server, it doesn't change the ${versionstring} section in the pom nor as the filename. (Which it should do)
Hope someone has an idea.
Thanks for reading. :)
--- Visual setup ---
parent:
<version>${versionstring}</version>
<properties>
<projectVersion>1.0</versionstring>
</properties>
<profiles>
<profile>
<id>example</id>
<properties>
<versionstring>${projectVersion}-SNAPSHOT</versionstring>
</properties>
</profile>
</profiles>
child:
<version>${versionstring}</version>
<parent>
<artifactId>***</artifactId>
<groupId>***</groupId>
<version>1.14.0.0-SNAPSHOT</version>
</parent>

Related

How to configure a default set of properties to be used in every new Maven project?

I'm learning Maven and writing a simple PowerShell script to quickly create a project from the command-line. I've noticed that when creating a project with the line:
mvn archetype:generate "-DgroupId=my.group.id" "-DartifactId=my-project" "-DarchetypeArtifactId=maven-archetype-quickstart" "-DarchetypeVersion=1.4" "-DinteractiveMode=false"
the following properties are present:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
I wanted my new projects to have this properties instead:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>11</maven.compiler.source>
</properties>
I've tried adding a "-Dmaven.compiler.release=11", but that didn't work. Adding the profile:
<profile>
<id>jdk-11</id>
<activation>
<jdk>11</jdk>
</activation>
<properties>
<maven.compiler.release>11</maven.compiler.release>
</properties>
</profile>
to the settings.xml file didn't help either.
Is there a way I can do this without having to manually modify the pom.xml file every time I create a project?
Thanks in advance!

Is it possible to specify multiple main class in pom file?

I am using Spring-boot to develop an application. The reason I need to specify multiple main classes is that, my program runs as a 'tool'. By starting with different main classes, I can finish tasks. I currently specify one main class in this way:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>com.lu.qe.ClassificationService</mainClass>
</configuration>
</plugin>
Then I can start my application by running at a terminal:
mvn spring-boot:run
This only runs the "ClassificationService" main class. I also want to be able to possibly run another main class, like "ClassificationService_2". In such a case, how to achieve this? Is it possible to let 'mvn spring-boot:run' take a parameter?
From command line argument main class can be pass but it will fail to run because multiple main class will be found..
mvn spring-boot:run -Dloader.main=DemoApplication
But I think you can manage it by defining multiple profiles and then in command line you can pass profile argument..not checked but should work.
<profiles>
<profile>
<id>profile1</id>
<properties>
<spring.boot.mainclass>com.MainClass1</spring.boot.mainclass>
</properties>
</profile>
<profile>
<id>profile2</id>
<properties>
<spring.boot.mainclass>com.MainClass2</spring.boot.mainclass>
</properties>
</profile>
</profiles>
I'm also developing a 'tool' that requires multiple main classes. springboot does not support this demand but I found maven parent pom feature exactly satisfy my requirement.
step 1 - to change a pom.xml to a parent pom, change the packaging type to 'pom', a parent pom looks like this:
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
step 2 - create another pom file let's say service1.xml, and set this, pay attention to the relativePath element:
<parent>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>./pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>service1</artifactId>
<version>0.0.1-SNAPSHOT</version>
step3 - then you can specify the pom file when run a mvn command
mvn -f service1.xml spring-boot:run
mvn -f service1.xml clean package

Maven profile file activation fails

I have a parent pom which defines profiles which shall be activated, when the defined folder exists:
<groupId>common</groupId>
<artifactId>common-build</artifactId>
<profiles>
<profile>
<id>dependency-profile-ejb</id>
<activation>
<file>
<exists>${basedir}/src/profile/dependency-ejb/</exists>
</file>
</activation>
<dependencies>[...]</dependencies>
</profile>
<profile>
<id>dependency-profile-jsf</id>
<activation>
<file>
<exists>${basedir}/src/profile/dependency-jsf/</exists>
</file>
</activation>
<dependencies>[...]</dependencies>
</profile>
</profiles>
I have a maven project with several submodules:
<parent>
<groupId>common</groupId>
<artifactId>common-build</artifactId>
</parent>
<groupId>project/groupId>
<artifactId>project-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<modules>
<module>project-child-one<module>
</modules>
In the child project I just define the parent dependency:
<parent>
<groupId>project</groupId>
<artifactId>project-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>project-child-one</artifactId>
and in this child project I have defined the folder src/profile/dependency-ejb.
If I run the build of the projects in eclipse everything works as expected. I have then installed the project in jenkins, but the build fails. If I checkout the project-parent into a clean directory and try to run a maven build, the build fails, too.
Why does the build run in eclipse but not in command line? Why is the profile definition in the parent pom of common-build not respected?
After some further tests I found the solution. The build failed, because the folders for the profile activation were missing. I have added the project to git and forgot that git does not commit/push empty folders.
The solution is to add an empty .gitkeep in the folders to force git to commit/push them.

Dependency hierarchy not using property from parent pom?

I have a problem I wonder if someone could help me to resolve.
I have a module structure in my project where I resolve dependencies using Maven. For this structure I have versions with different content I distinguish using classifiers. For each classifier I have defined a profile in a parent pom with the string for the classifier in a property. This way in my modules I use this property and is the profile I defined who decides the classifier constant.
The problem I'm stuck with now is the dependency hierarchy not recognizing the classifier when a dependency is inherit from the one I define in the pom of one of my modules.
For example, if I have projects A, B and C, B depends on A and C depends on B, from C I'm getting B with the classifier but not A with it.
This happens if I use the property from the parent pom. If I use directly a constant string instead, the dependencies get caught correctly.
The only solution I see is using profiles on each pom defining the dependencies inside them. But I have 5 profiles! Isn't there any other way to resolve this?
I'm using STS 3.8 with m2e plugin as my IDE.
Thank you in advance!
I add the poms
parent pom:
<profiles>
<profile>
<id>TRUNK</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<svnBranch />
</properties>
</profile>
<profile>
<id>MON</id>
<properties>
<svnBranch>MON</svnBranch>
</properties>
</profile>
<profile>
<id>LOLA</id>
<properties>
<svnBranch>LOLA</svnBranch>
</properties>
</profile>
<profile>
<id>NBA</id>
<properties>
<svnBranch>NBA</svnBranch>
</properties>
</profile>
<profile>
<id>TEST</id>
<properties>
<svnBranch>TEST</svnBranch>
</properties>
</profile>
<profile>
<id>PROD</id>
<properties>
<svnBranch>PROD</svnBranch>
</properties>
</profile>
</profiles>
Project A:
<parent>
<groupId>com.myproject</groupId>
<artifactId>pom</artifactId>
<version>1.0.10</version>
</parent>
<artifactId>core-services</artifactId>
<version>1.1.0.41-SNAPSHOT</version>
Project B:
<parent>
<groupId>com.mycompany</groupId>
<artifactId>pom</artifactId>
<version>1.0.10</version>
</parent>
<artifactId>olb-services</artifactId>
<version>1.1.0.41-SNAPSHOT</version>
<properties>
<module.core-services.dependency.version>1.1.0.41-SNAPSHOT</module.core-services.dependency.version>
</properties>
<dependencies>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>core-services</artifactId>
<version>${module.core-services.dependency.version}</version>
<classifier>${svnBranch}</classifier>
</dependency>
</dependencies>
Project C:
<parent>
<groupId>com.mycompany</groupId>
<artifactId>pom</artifactId>
<version>1.0.10</version>
</parent>
<artifactId>nba-services</artifactId>
<version>1.1.0.41-SNAPSHOT</version>
<properties>
<module.olb-services.dependency.version>1.1.0.41-SNAPSHOT</module.olb-services.dependency.version>
<module.core-services.dependency.version>1.1.0.41-SNAPSHOT</module.core-services.dependency.version>
</properties>
<dependencies>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>olb-services</artifactId>
<version>${module.olb-services.dependency.version}</version>
<classifier>${svnBranch}</classifier>
</dependency>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>core-services</artifactId>
<version>${module.core-services.dependency.version}</version>
<classifier>${svnBranch}</classifier>
</dependency>
</dependencies>
Using the ${svnBranch} in the classifier tag for each dependency doesn't work. It looks like in project B, when is referenced by project C, the property ${svnBranch} is empty nevertheless it comes from the parent pom.
In maven, you can only use a profile defined at the parent level in your child pom, if you can only activate it at built time by passing -D{activation.property}=value or -P{profile.id/s} .
You cannot define a profile in your parent and try it to activate in your child pom as profile can not be inherited(you are not even trying to activate in the child pom in your case as per your example).
in another word,unless the profile is activate by default maven doesn't know about it (you might be tempted to activate everything by default in your case, but bear in mind only one profile can be activate by default at the time)
your problem is ${svnBranch} from TRUNK is only present in your child pom and has no value, therefore maven only acts on the GAV and not the classifier. and to prove that check your child's effective pom (mvn help:effective-pom). also you can check which of your profile are active and which are not (mvn help:all-profiles).
I don't think using profiles is the best approach for what you are doing. A better/simpler approach maybe be to just declare your branch names in normal properties in your parent for example.
<properties>
<svnBranch.lola>LOLA</svnBranch.lola>
<svnBranch.nba>NBA</svnBranch.nba>
</properties>
then your child uses as needed.
<dependencies>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>olb-services</artifactId>
<version>${module.olb-services.dependency.version}</version>
<classifier>${svnBranch.lola}</classifier>
</dependency>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>core-services</artifactId>
<version>${module.core-services.dependency.version}</version>
<classifier>${svnBranch.nba}</classifier>
</dependency>
</dependencies>

How do I use pom.xml profile properties with pom aggregation?

I am using a pom.xml to aggregate various builds. I'd like to setup profiles with settings that apply to multiple pom.xml files. So, I have something like
<project>
....
<modules>
<module>project1</module>
<module>project2</module>
</modules>
<profiles>
<profile>
<id>local</id>
<properties>
<my.setting>setting</my.setting>
</properties>
<profile>
</profiles>
</project>
However, my.setting doesn't seem to get put into the child modules. How do get this to work?
The problem is that you are using only aggegration. But you must use inheritance in the child modules which means to have a parent entry in there. Then the information will be propagated to the childs.

Resources