pom.xml selecting profile from multiple profiles - spring-boot

I have a application with multiple build profiles all stated in my pom.xml, I have something like this below.
<profiles>
<profile>
<id>sit</id>
</profile>
<profile>
<id>uat</id>
</profile>
</profiles>
how do I now specify, during running, i want to use sit or uat profile? when it compiles and run, how does spring boot decide which profile to pick?

You can provide the active profile name in application properties or at the command line while staring the application with --spring.profiles.active=sit
Please check this for more information https://docs.spring.io/spring-boot/docs/1.2.0.M1/reference/html/boot-features-profiles.html

Related

Having trouble getting springboot app to run/build specific profile

I am using Maven as my build tool.
For profile management in SpringBoot I am using yml files.
For my SpringBoot app, I have the following application-*.yml files set up:
application.yml
application-local.yml
application-foobar.yml
My corresponding pom.xml profile configuration:
<profiles>
<profile>
<id>local</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<activatedProperties>local</activatedProperties>
</properties>
</profile>
<profile>
<id>foobar</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<activatedProperties>foobar</activatedProperties>
</properties>
</profile>
</profiles>
Whenever I attempt to either package or run my app via Maven:
> mvn package -P <any configured profile>
> mvn spring-boot:run -P <any configured profile>
The app runs, however it only runs falling back to the default profile (application.yml).
I get the following log entry every time I attempt to run the application under any of my configured profiles:
: No active profile set, falling back to default profiles: default
I can't seem to find any clear information on the internet regarding this issue.
Any help would be greatly appreciated. Thanks!
Maven build profiles and Spring bean profiles are two completely separate concepts that happen to use the same name but do not interact with each other.
The XML you showed with <profiles></profiles> configures Maven build profiles, but will not have any effect on Spring bean profiles.
Per the Spring Framework documentation on activating a profile and Spring Boot documentation on passing arguments when running an application, you can select the active Spring bean profile when running the app using Maven with a command like this:
> mvn spring-boot:run -Dspring-boot.run.jvmArguments="-Dspring.profiles.active=local"

Goal specific javax.net.ssl.trustStore

I've got a Maven project for which i use org.apache.tomcat.maven:tomcat6-maven-plugin to deploy to a remote Tomcat.
This tomcat is configured so that i need to specify:
-Djavax.net.ssl.trustStore=mykeystore.jks -Djavax.net.ssl.trustStorePassword=mypassword
My problem is that by doing so, I can't download dependencies anymore from remote repositories through my company proxy as it tries to establish a secure connection using this truststore and it fails...
I'm looking for a way to connect to both ends (maven repo and my remote tomcat) without having to set/unset my MAVEN_OPTS variable every time...
I've seen that I can have a <configuration /> element in my settings.xml, but I can't find what to put in it.
Thanks...
Using different profiles with maven:
Define the active profiles in your pom (you can also define profiles in settings.xml but I think this should work for your case):
<profiles>
<profile>
<id>TOMCAT_DEPLOY</id>
<activation>
// Rules to active the profile
<activeByDefault>true</activeByDefault>
</activation>
<properties>
</properties>
// Add rest of profile specific configuration
</profile>
</profiles>
For executing maven with an specific profile, basically you have a list of active profiles and you can execute one of them according to different triggers:
A profile can be triggered/activated in several ways:
Explicitly, Through Maven settings, Based on environment variables OS settings or based on some Present or missing files
Please, read this link where you can have all information about profiles and how activate them for any execution

Maven - Is it possible to build a project specifying multiple profiles simultaneously?

We are developing a Maven archetype for applications that only consume web services. This archetype offers three profiles, one for each environment (dev, pre, pro).
The point is that we would like to offer the possibility of having ORM dependencies included optionally (JPA, Hibernate) for those project that may require them in the future. We had though of creating an additional profile containing those dependencies.
When we build our project we use mvn package -Denvironment=dev. Is it possible to specify more than one profile such as: mvn package -Denvironment=dev,orm?
Yes, this is possible. But it seems you are confused about how profiles are activated in the first place.
The command
mvn package -Denvironment=dev
will not activate any profile without further configuration. In your case, it works because there must be a profile definition in your POM that is activated by the presence of the system property environment with a value of dev. The configuration you have would look like:
<profiles>
<profile>
<activation>
<property>
<name>environment</name>
<value>dev</value>
</property>
</activation>
</profile>
</profiles>
This is the magic that makes the profile activates when you pass the system property with -Denvironment. With that in mind, you can activate multiple profiles with the same idea: declare multiple <profile> element that are activated by the presence of a system property.
<profiles>
<profile>
<activation>
<property>
<name>myAwesomeProperty1</name>
<value>true</value>
</property>
</activation>
</profile>
<profile>
<activation>
<property>
<name>myAwesomeProperty2</name>
<value>true</value>
</property>
</activation>
</profile>
</profiles>
The above configuration would activate both profile if myAwesomeProperty1 and myAwesomeProperty2 is a system property with the value true.
In this particular case though, it seems that what you want is to activate a build depending on your environment so it could perhaps be a better idea to activate the profiles based on the -P command line switch, instead of a system property.
From Introduction to Build Profiles:
Profiles can be explicitly specified using the -P CLI option.
This option takes an argument that is a comma-delimited list of profile-ids to use. When this option is specified, the profile(s) specified in the option argument will be activated in addition to any profiles which are activated by their activation configuration or the <activeProfiles> section in settings.xml.
mvn groupId:artifactId:goal -P profile-1,profile-2
With this solution, you invoke Maven with multiple profile ids. That is to say, if you have in your configuration
<profiles>
<profile>
<id>profile-1</id>
<!-- rest of config -->
</profile>
<profile>
<id>profile-2</id>
<!-- rest of config -->
</profile>
</profiles>
The above invocation would activate both profile-1 and profile-2.

Enable certain Maven tests by passing a command line switch

I have a single module project that has some unit tests that require an external hardware device. I don't want these tests to execute unless I indicate that the device is available.
I feel like this is solvable using Maven properties and the SureFire exclusion/inclusion configuration, but I can't quite see how to do it. A similar question shows how to disable/enable all the tests in a project based on a Maven property, but doesn't quite answer my issue.
In summary, I wish to identify a pattern (e.g. **/*ResourceTest.java) that describes the tests I don't want to run, unless I pass a Maven property to enable them.
E.g.
mvn clean install (runs the standard tests, but skips device-related tests)
mvn -Drun.device.tests=true clean install (runs all the tests)
Thanks in advance.
(Edited to remove the misleading usage of the word "resource" > replaced with "hardware device").
You also can just use the JUnit Assume methods to decide (inside the test) if a test should be executed or skipped.
The best option IMHO would however be to 'declare' the device dependend tests to be "integration tests" and let them be executed by the Maven Failsafe Plugin. I think this would be the "build in" maven solution without any profile 'magic'.
The link you provided gave the good answer.
The right way
Use a mix of Profile Management and Surefire Configuration inclusion / exlcusion is the right way.
You should ask yourself WHY you want to activate some tests dependings on a resource. The resource should always been in your classpath.
If not, you probably just want to activate some test manually, for some tricky reasons. In that case consider this is a bad use of Maven (how would you automate that on a distant server for instance ?)
What you asked
If you really really want to do that, because you have some good reasons that we are not aware of, simply use this :
This example will trigger the profile when the generated file target/generated-sources/axistools/wsdl2java/org/apache/maven is missing.
Example from Maven official doc : http://maven.apache.org/guides/introduction/introduction-to-profiles.html
<profiles>
<profile>
<activation>
<file>
<missing>target/generated-sources/axistools/wsdl2java/org/apache/maven</missing>
</file>
</activation>
...
</profile>
</profiles>
As of Maven 2.0.9, the tags and could be interpolated. Supported variables are system properties like ${user.home} and environment variables like ${env.HOME}. Please note that properties and values defined in the POM itself are not available for interpolation here, e.g. the above example activator cannot use ${project.build.directory} but needs to hard-code the path target.
You could find more information here : http://www.sonatype.com/books/mvnref-book/reference/profiles-sect-activation.html
Hope that will help.
Don't hesitate to challenge my point of view with you own reasons (even legacy code ;) ) or experience
To expand on #Jean-Rémy answer, I have done the following in my project POM file:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12</version>
<configuration>
<excludes>
<exclude>${tests.to.skip}</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<!-- This profile will be used when running tests without a device -->
<id>default-profile</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<tests.to.skip>**/*DeviceTest.java</tests.to.skip>
</properties>
</profile>
<profile>
<id>device-profile</id>
<activation>
<property>
<name>device</name>
<value>true</value>
</property>
</activation>
<properties>
<!-- Unsure how to match nothing -->
<tests.to.skip>NOTHING</tests.to.skip>
</properties>
</profile>
This creates two profiles, the default profile will exclude the device tests, whereas the "device-profile" will execute all tests.
To execute the device profile, one can execute mvn -Ddevice=true test.

Is there a way to achieve reverse of maven profile activation by property?

I want to have a profile that triggers a certain plugin(say PMD) but I want to explicitly disable that plugin execution sometimes.
So I want to have a profile that is always active except when a property is defined.
Something like mvn -Dnopmd clean install, and the profile gets de-activated. Other than that the profile should always be active.
You can activate a profile when a property is not specfied like so:
<profile>
<id>someprofile</id>
<activation>
<property>
<name>!property.name</name>
</property>
</activation>
</profile>
This is also explained in the Maven documentation, Introduction to Build Profiles.

Resources