I'm trying to activate profiles of an AppEngine application using the maven command like the following :
mvn appengine:deploy -Dspring.profiles.active=prod
But it is ignored.
Is it possible to activate profiles using maven ?
I succeeded by linking Maven Profiles to Spring Profiles. In the following I explain how I did :
1 - Create Maven Profiles:
In pom.xml I identified my maven profiles, and will link them later to spring profiles by storing them in "spring.profiles.to.activate" property :
<!-- PROFILES -->
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<spring.profiles.to.active>dev</spring.profiles.to.active>
</properties>
</profile>
<profile>
<id>uat</id>
<properties>
<spring.profiles.to.active>uat</spring.profiles.to.active>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<spring.profiles.to.active>prod</spring.profiles.to.active>
</properties>
</profile>
</profiles>
2 - Activate Maven filtering :
I activated filtering in folder ${basedir}/src/main/webapp, by adding maven-war-plugin to build.
This will allow us to resolve placeholders ${...} (In this particular case ${spring.profiles.to.activate}) in the mentioned folder.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webResources>
<resources>
<directory>${basedir}/src/main/webapp/WEB-INF</directory>
<filtering>true</filtering>
<targetPath>WEB-INF</targetPath>
</resources>
</webResources>
</configuration>
</plugin>
3- Activate profile Spring
In appengine-web.xml declare the system property : "spring.profiles.active" as being the maven property ${spring.profiles.to.activate}
<appengine-web-app
xmlns="http://appengine.google.com/ns/1.0">
<version>1</version>
<threadsafe>true</threadsafe>
<runtime>java8</runtime>
<system-properties>
<property name="spring.profiles.active" value="${spring.profiles.to.active}" />
</system-properties>
</appengine-web-app>
4 - Deploy to Appengine
# Dev
mvn appengine:deploy -Pdev
# UAT
mvn appengine:deploy -Puat
#PROD
mvn appengine:deploy -Pprod
#dev profile, try adding space between -P and dev
mvn appengine:deploy -P dev
#uat profile, try adding space between -P and uat
mvn appengine:deploy -P qa
#prod profile, try adding space between -P and prod
mvn appengine:deploy -P prd
Related
I have a Spring Boot application build on Maven. I'm using Spring profiles to distinguish environment-specific configuration. I would like to prevent running tests when a specific Spring profile is active. Reason: I would like to prevent running tests with production properties (spring.profiles.active=prod). I would like to do this globally (maybe with some Maven plugin) instead of on each test separately.
Do you have any checked solutions for this?
<profiles>
<profile>
<id>prod</id>
<properties>
<maven.test.skip>true</maven.test.skip>
</properties>
</profile>
</profiles>
You can use #IfProfileValue annotation. But you have to add some values to your active profile and read it with mentioned annotation. You can read more here (section 3.4.3): https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#integration-testing
EDIT:
Another solution is to exclude all (or selected tests) tests in the Surefire plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<exclude>${exclude.tests}</exclude>
</excludes>
</configuration>
</plugin>
...
<profile>
<id>prod</id>
<properties>
<exclude.tests>**/*.*</exclude.tests>
</properties>
</profile>
And then when you run mvn clean test -Pprod all tests will be skipped
It is in my understanding that when a profile is explicitly set with the -P option, it is exclusive and that profile should get activated no matter what.
In my case, after running the command mvn clean compile -Pcross-compile, the cross-compile profile was ignored and build-linux-amd64 was activated instead.
What is going on here and why is cross-compile not being called?
My profile configuration below:
<profiles>
<!-- Cross-compile profile (can only be run under linux os) -->
<profile>
<id>cross-compile</id>
<properties>
<current-os>linux</current-os>
<current-arch>amd64</current-arch>
<crossCompile>true</crossCompile>
<build-target>native-build-cc-all</build-target>
</properties>
<build>
<plugins>
<!-- Enforcer: Make sure this can only be run from the Linux OS -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<executions>
<execution>
<id>enforce-os</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireOS>
<name>Linux</name>
<family>unix</family>
<arch>amd64</arch>
</requireOS>
</rules>
<failFast>true</failFast>
<fail>true</fail>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<!-- BUILD PROFILE: Linux - x86_64/amd64 -->
<profile>
<id>build-linux-amd64</id>
<activation>
<os>
<name>linux</name>
<family>unix</family>
<arch>amd64</arch>
</os>
<property>
<name>!crossCompile</name>
</property>
</activation>
<properties>
<current-os>linux</current-os>
<current-arch>amd64</current-arch>
<build-target>native-build-linux-x86_64</build-target>
</properties>
</profile>
</profiles>
pom.xml source code here
Travis CI Log here
Looks like I need to explicitly deactivate the build-linux-amd64 profile. I compiled using
mvn clean compile -P'cross-compile,!build-linux-amd64'
and now it works as expected.
From what you provided in Travis log, I find you are running maven with
mvn --settings scripts/settings.xml install -DskipTests=true -Dgpg.skip -Dmaven.javadoc.skip=true -B -V
In this step, you were compiling the code without profile option.
Then you run
mvn package -Pcross-compile -DskipTests=true -Dgpg.skip -Dmaven.javadoc.skip=true.
In this packing step, the code is compiled. So mvn will not use the compile options in the profile to compile the code again.
So try to add the profile option in the first mvn install command.
I have 2 profiles in Maven's settings.xml but I cannot trigger them by the -P option, always the second is used:
<profiles>
<profile>
<id>wilfly-local</id>
<activeByDefault>true</activeByDefault>
<properties>
<wildfly-hostname>127.0.0.1</wildfly-hostname>
<wildfly-port>zzzz</wildfly-port>
<wildfly-username>xxx</wildfly-username>
<wildfly-password>S3cret</wildfly-password>
</properties>
</profile>
<profile>
<id>wildfly-remote</id>
<activeByDefault>false</activeByDefault>
<properties>
<wildfly-hostname>192.168.xxx.yyy</wildfly-hostname>
<wildfly-port>zzzz</wildfly-port>
<wildfly-username>xxx2</wildfly-username>
<wildfly-password>S3cret</wildfly-password>
</properties>
</profile>
</profiles>
...
<activeProfiles>
<activeProfile>wildfly-local</activeProfile>
<activeProfile>wildfly-remote</activeProfile>
</activeProfiles>
My pom.xml:
...
<build>
<finalName>mvnweb</finalName>
<plugins>
<plugin>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>1.2.1.Final</version>
<configuration>
<hostname>${wildfly-hostname}</hostname>
<port>${wildfly-port}</port>
<username>${wildfly-username}</username>
<password>${wildfly-password}</password>
</configuration>
</plugin>
</plugins>
</build>
...
The problem is when I try mvn wildfly:deploy -P wildfly-local, Maven deploys the war file on the remote server.
When I change the order of profiles then the second one is used (I checked it with -X option when I ran it). Both profiles deploys the project properly.
The activeByDefault tag do nothing, if I comment it out the result remains the same.
Can somebody tell me what should I do to get -P trigger work properly?
Thanks in advance!
From documentation:
The final piece of the settings.xml puzzle is the activeProfiles element. This contains a set of activeProfile elements, which each have a value of a profile id. Any profile id defined as an activeProfile will be active, reguardless of any environment settings. If no matching profile is found nothing will happen. For example, if env-test is an activeProfile, a profile in a pom.xml (or profile.xml with a corrosponding id will be active. If no such profile is found then execution will continue as normal.
Since you have both your profiles specified in your settings.xml they are activated both. Second one probably overwrites properties.
You should remove your activeProfiles from settings.xml if you want enable then only by -P CLI argument
<activeProfiles>
<activeProfile>wildfly-local</activeProfile>
<activeProfile>wildfly-remote</activeProfile>
</activeProfiles>
I'm trying to set an active profile in Spring Boot application using Maven 3.
In my pom.xml I set default active profile and property spring.profiles.active to development:
<profiles>
<profile>
<id>development</id>
<properties>
<spring.profiles.active>development</spring.profiles.active>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
</profiles>
but every time I run my application, I receive the following message in logs:
No active profile set, falling back to default profiles: default
and the SpringBoot profile is set to default (reads application.properties instead application-development.properties)
What else should I do to have my SpringBoot active profile set using Maven profile?
Any help highly appreciated.
The Maven profile and the Spring profile are two completely different things. Your pom.xml defines spring.profiles.active variable which is available in the build process, but not at runtime. That is why only the default profile is activated.
How to bind Maven profile with Spring?
You need to pass the build variable to your application so that it is available when it is started.
Define a placeholder in your application.properties:
spring.profiles.active=#spring.profiles.active#
The #spring.profiles.active# variable must match the declared property from the Maven profile.
Enable resource filtering in you pom.xml:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
…
</build>
When the build is executed, all files in the src/main/resources directory will be processed by Maven and the placeholder in your application.properties will be replaced with the variable you defined in your Maven profile.
For more details you can go to my post where I described this use case.
Or rather easily:
mvn spring-boot:run -Dspring-boot.run.profiles={profile_name}
There are multiple ways to set profiles for your springboot application.
You can add this in your property file:
spring.profiles.active=dev
Programmatic way:
SpringApplication.setAdditionalProfiles("dev");
Tests make it very easy to specify what profiles are active
#ActiveProfiles("dev")
In a Unix environment
export spring_profiles_active=dev
JVM System Parameter
-Dspring.profiles.active=dev
Example: Running a springboot jar file with profile.
java -jar -Dspring.profiles.active=dev application.jar
You can run using the following command. Here I want to run using spring profile local:
spring-boot:run -Drun.jvmArguments="-Dspring.profiles.active=local"
In development, activating a Spring Boot profile when a specific Maven profile is activate is straight. You should use the profiles property of the spring-boot-maven-plugin in the Maven profile such as :
<project>
<...>
<profiles>
<profile>
<id>development</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<profiles>
<profile>development</profile>
</profiles>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profiles>
</...>
</project>
You can run the following command to use both the Spring Boot and the Maven development profile :
mvn spring-boot:run -Pdevelopment
If you want to be able to map any Spring Boot profiles to a Maven profile with the same profile name, you could define a single Maven profile and enabling that as the presence of a Maven property is detected. This property would be the single thing that you need to specify as you run the mvn command.
The profile would look like :
<profile>
<id>spring-profile-active</id>
<activation>
<property>
<name>my.active.spring.profiles</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<profiles>
<profile>${my.active.spring.profiles}</profile>
</profiles>
</configuration>
</plugin>
</plugins>
</build>
</profile>
And you can run the following command to use both the Spring Boot and the Maven development profile :
mvn spring-boot:run -Dmy.active.spring.profiles=development
or :
mvn spring-boot:run -Dmy.active.spring.profiles=integration
or :
mvn spring-boot:run -Dmy.active.spring.profiles=production
And so for...
This kind of configuration makes sense as in the generic Maven profile you rely on the my.active.spring.profiles property that is passed to perform some tasks or value some things.
For example I use this way to configure a generic Maven profile that packages the application and build a docker image specific to the environment selected.
You should use the Spring Boot Maven Plugin:
<project>
...
<build>
...
<plugins>
...
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.5.1.RELEASE</version>
<configuration>
<profiles>
<profile>foo</profile>
<profile>bar</profile>
</profiles>
</configuration>
...
</plugin>
...
</plugins>
...
</build>
...
</project>
I would like to run an automation test in different environments.
So I add this to command maven command:
spring-boot:run -Drun.jvmArguments="-Dspring.profiles.active=productionEnv1"
Here is the link where I found the solution: [1]https://github.com/spring-projects/spring-boot/issues/1095
I wanted to clarify the excellent answer https://stackoverflow.com/a/42391322/13134499 from Daniel Olszewski if you want to use it just for tests.
How to bind Maven profile with Spring for tests?
As you did, define the variable in pom.xml
...
<properties>
<spring.profiles.active>development</spring.profiles.active>
</properties>
Define a placeholder in your application-test.properties in src/test/resources:
spring.profiles.active=#spring.profiles.active#
Enable resource filtering in you pom.xml:
<build>
...
<testResources>
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
</testResource>
<testResources>
</build>
file structure:
/src/main/resources
=>
application.properties:
spring.profiles.active:#spring.profiles.active#'
application-dev.properties
application-prod.properties
IDE-Eclipse:
Right click on the project=>Run As=>Run Configuration=>Arguments=>VM Arguments:-Dspring.profiles.active=dev
CMD:
mvn spring-boot:run -Dspring.profiles.active=dev
mvn clean install -Dspring.profiles.active=dev
I have two profiles for different environments in pom.xml, I have to run mvn -PTest1 install and mvn -PTest2 install command to get these profiles in use. Can we integrate two separate maven commands in a single one (like mvn clean install)?
Here is my Pom entry
<profiles>
<profile>
<id>Test1</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.5</jdk>
<os>
<name>Windows XP</name>
<family>Windows</family>
<arch>x86</arch>
<version>5.1.2600</version>
</os>
<property>
<name>sparrow-type</name>
<value>African</value>
</property>
</activation>
<dependencies>
<dependency>
<groupId>
com.endeca
</groupId>
<artifactId>
endeca_navigation_Test1
</artifactId>
<version>
6.1
</version>
<!--<version>stable</version> -->
<scope>
compile
</scope>
</dependency>
</profile>
<profile>
<id>Test2</id>
<activation>
<activeByDefault>false</activeByDefault>
<jdk>1.5</jdk>
<os>
<name>Windows XP</name>
<family>Windows</family>
<arch>x86</arch>
<version>5.1.2600</version>
</os>
<property>
<name>sparrow-type</name>
<value>African</value>
</property>
</activation>
<dependencies>
<dependency>
<groupId>
com.endeca
</groupId>
<artifactId>
endeca_navigation_Test2
</artifactId>
<version>
6.1
</version>
<!--<version>stable</version> -->
<scope>
compile
</scope>
</dependency>
</dependencies>
</profile>
</profiles>
It will helpfull to manage hudson job using single command
Based on the documentation and discussion here, try separating profile names with a comma:
mvn install -P Test1,Test2
Mifeet's answer is correct, but in Windows PowerShell you should quote parameters, otherwise you'll get "unknown lifecycle phase" error.
mvn install -P 'Test1,Test2'
For me Mifeet's answer isn't working. I get "unknown lifecycle phase Test2". For me this is working:
mvn install -PTest1 -PTest2
Based on the maven help command
-P,--activate-profiles <arg> Comma-delimited list of profiles to activate
So you can run mvn package -Pp1,p2 to run profile id with p1 and p2