How to parameterize a Maven file (pom.xml)? - java

I have a spring boot application where I want to package it according to the profile I am building with, for example when I issue profile x, I want maven to build as a jar; but when building with profile y, I want maven to build as a war.
I want something like:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0.0</version>
<package>${buildMethod}</package>
</project>
Where ${buildMethod} is the type of packaging.
This would be decided by executing a command i.e. mvn package -P buildProfile.

Maybe this would help:
<profiles>
<profile>
<id>war</id>
<properties>
<deploy.type>war</deploy.type>
</properties>
</profile>
<profile>
<id>jar</id>
<properties>
<deploy.type>jar</deploy.type>
</properties>
</profile>
</profiles>
And then just use this property placeholder ${deploy.type}.

You can easily add profiles, with a list of properties, to your pom file.
Build using:
mvn package - Builds a WAR by default (implicit)
mvn package -P deployWar - Builds a WAR
mvn package -P deployJar - Builds a JAR
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0.0</version>
<package>${deployment.type}</package>
<profiles>
<!-- This profile deploys the application as a WAR (default) -->
<profile>
<id>deployWar</id>
<properties>
<deployment.type>war</deployment.type>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<!-- This profile deploys the application as a JAR -->
<profile>
<id>deployJar</id>
<properties>
<deployment.type>jar</deployment.type>
</properties>
</profile>
</profiles>
</project>

Related

how to include specific applicaction.properties in spring boot war

I need to create different application properties for a spring boot project and include the proper one in the generated war. I'm able to generate a war, but no to include the proper file in it. I have different profiles created, and different application.properties following the pattern application-env.properties where env is (dev, cert...), all of then placed in src/main/resources but I'm not able to pick the proper one and include in the generated war, even including "-Dspring.profiles.active=cert" to define the profile active. The war is generated with all of them. Any idea?
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<build.profile.id>dev</build.profile.id>
<packaging.type>jar</packaging.type>
<spring.profiles.active>dev</spring.profiles.active>
</properties>
</profile>
<profile>
<id>cert</id>
<properties>
<build.profile.id>cert</build.profile.id>
<spring.profiles.active>cert</spring.profiles.active>
<packaging.type>war</packaging.type>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</profile>
</profiles>

Maven Compile cant find src/main/resources directory

I am trying to setup an integration-test environment using Maven for my project but am getting the below error when I run the Compile goal.
[ERROR] Failed to execute goal
org.apache.maven.plugins:maven-resources-plugin:3.0.2:resources
(default-resources) on project mavenintegrationtest: Error loading
property file
'/Users/xxx/dev/poc/java/mavenintegrationtest/profiles/dev/config.properties'
-> [Help 1]
The error seems to be complaining that it cant find the config.properties file in that location which is correct. For some reason it has removed the "src/main/resources" bit from the file path.
So the correct full path is,
/Users/xxx/dev/poc/java/mavenintegrationtest/src/main/resources/profiles/dev/config.properties
but for some reason its removed src/main/resources and so is looking in,
/Users/xxx/dev/poc/java/mavenintegrationtest/profiles/dev/config.properties
Does anyone know whats causing this ?
My POM is as shown below and I get this error when I uncomment the following "filter" tag,
<filter>${basedir}/profiles/${build.profile.id}/config.properties</filter>
I've tried removing the ${basedir} statement and still get the same error.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.stackoverflow</groupId>
<artifactId>mavenintegrationtest</artifactId>
<version>1.0-SNAPSHOT</version>
<name>mavenintegrationtest</name>
<url>http://www.example.com</url>
<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>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<filters>
<filter>${basedir}/profiles/${build.profile.id}/config.properties</filter>
</filters>
<resources>
<resource>
<filtering>true</filtering>
<directory>${basedir}/src/main/resources</directory>
</resource>
</resources>
</build>
<!-- Profile configuration -->
<profiles>
<!-- The configuration of the development profile -->
<profile>
<id>dev</id>
<!-- The development profile is active by default -->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<build.profile.id>dev</build.profile.id>
</properties>
</profile>
<!-- The configuration of the integration-test profile -->
<profile>
<id>integration-test</id>
<properties>
<build.profile.id>integration-test</build.profile.id>
</properties>
</profile>
</profiles>
</project>
The filter (link) element will parse your files and apply a content filter on them.
The profiles (link) element helps you define different environments for the build.
All of this as to do with your resources. These can be configuration files, or other type of files. If you filter then you can change the content of this files with other values - e.g. pom properties. When using profiles you can have different replacement properties for each environment.
You should move the profiles up in the tree for the default path, or add a configuration in your pom for the resource location.
The base dir is the folder containing your pom. You should have your profile folder here.
Also, here is some good information about profiles and its configurations.

Maven dependency only for testing purposes

I have a maven dependency like this:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>${version}</version>
</dependency>
And the thing is that the ${version} property should be replaced by 1.8.1.RELEASE or 1.9.0.RELEASE depending on the profile I choose when installing, but for testing purposes only the 1.9.0.RELEASE should be used, even if I'm using the 1.8.1 profile. Is there a way to do this? I tried using the test scope but it didn't work as I think it would.
Would something like this work for you?
<profiles>
<profile>
<id>defaultProfile</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<magicVersion>1.9.0.RELEASE</magicVersion>
</properties>
</profile>
<profile>
<id>Release181</id>
<properties>
<magicVersion>1.8.1.RELEASE</magicVersion>
</properties>
</profile>
<profile>
<id>test</id>
<properties>
<magicVersion>1.9.0.RELEASE</magicVersion>
</properties>
</profile>
</profiles>
The idea being is activating the test profile will overwrite the version even if it's been set already by your 1.8.1 profile. Use case would be;
mvn -P Release181,test test

How to specify packaging in a Maven profile?

I have a project which can be packaged and deployed two different ways, it's either a WAR for Tomcat, or a shaded JAR for AWS Lambda. Currently this isn't working very well, I have to keep changing the pom.xml back and forth when doing a release. Is there a way to accomplish this with Maven profiles?
e.g., I'd like to do
mvn install -Pwar
to generate the WAR, and
mvn install -Plambda
to generate the shaded JAR.
Is this possible?
You can try to include the following in your pom.xml
<packaging>${packaging.type}</packaging>
<profiles>
<profile>
<id>lambda</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<packaging.type>jar</packaging.type>
</properties>
</profile>
<profile>
<id>war</id>
<properties>
<packaging.type>war</packaging.type>
</properties>
</profile>
</profiles>

Maven build all sub-modules even with a profile

I have following segment in the parent pom.xml file
<groupId>my.group</groupId>
<artifactId>artifact</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<modules>
<module>../A</module>
<module>../B</module>
</modules>
<profiles>
<profile>
<id>P1</id>
<modules>
<module>../B</module>
</modules>
</profile>
<profiles>
When i try to execute the compile goal of this pom file with the profile P1 (In IDEA 14 Maven Projects window) it will compile the both module A and B.
But if I remove the modules segment, It will compile only the module B. (as mention in the profile)
<modules>
<module>../A</module>
<module>../B</module>
</modules>
But i want to keep the modules tag as it is and use profile to compile only the module B. Is there any solution to overcome this issue.
You have to create a separate profile for building both module A and B. You can have this profile active by default. So that will not change the existing behavior.
<groupId>my.group</groupId>
<artifactId>artifact</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<profiles>
<profile>
<id>P1</id>
<modules>
<module>../B</module>
</modules>
</profile>
<profile>
<id>Everything</id>
<modules>
<module>../A</module>
<module>../B</module>
</modules>
</profile>
<profiles>

Categories