Could i use maven profile to swith between different value application.properties - maven

I have application-prod.yml application-dev.yml, and application.properties which containing just one line code like below
spring.profiles.active=dev
for maven production build, it should use spring.profiles.active=prod , then it will build with application-prod.yml, for development build, it should use spring.profiles.active=dev, then maven
will use application-dev.yml to build
could I use pom.xml's different profile to do switch for this value switch in applicaiton.properties?

You can use a Maven property for this, reference it in your yml file (with ${...}) and filter the resource (i.e. the yml file) with the maven resources plugin.

It seems that what you're after is "externalized configuration". According to the excellent 12factor guidelines, it is best not to keep such config inside your code-repository.
Refer to the relevant section in the Spring Boot manual to see which options you have (and there are many). What it comes down to is that you provide your application.yml/properties file on the filesystem and your application will read it from there, rather than from the classpath.
Also, note that spring-profiles are not meant to be used to distinguish between development environments, but rather to put the application in different functional modes (e.g. to enable or disable specific features).

If you want the content of your properties file changed at build time, then you can use Maven filtering. Maven filtering allows to replace a placeholder in your properties (or yaml) file by values from Maven properties.
Assuming you have a property in your POM called targetEnv, which might have either the value dev or prod (depending on the active Maven profile), then you can refer it in your properties file (or yaml file) by using the following syntax :
spring.profiles.active=#targetEnv#
However, if you want to follow Spring Boot recommandations, it is better to enable and disable the Spring profiles by the means of environment variables in your target environment. For instance, you can use an environment variable spring.profiles.active with the desired value and it will override the value in your properties file.

You need to define a custom property in each of your Maven profiles and set their values to match with suffixes of corresponding properties files that you want to load with a particular profile.
<profile>
<id>dev</id>
<properties>
<activatedProperties>dev</activatedProperties>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>release</id>
<properties>
<activatedProperties>release</activatedProperties>
</properties>
</profile>
Next, in the build section of the same file, configure filtering for the Resources Plugin. That will allow you to insert properties defined in the previous step into any file in the resources directory, which is the subsequent step.
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
…
</build>
Finally, add the following line to the application.properties.
spring.profiles.active=#activatedProperties#
For more details, please see spring boot properties per maven profile
For official guide to load from external configLoad from external Config

Related

How does maven replace text #env# in application.yml?

There is some profiles defined in pom.xml.
<profile>
<id>test</id>
<properties>
<env>test</env>
</properties>
</profile>
spring.profiles.active: #env# defined in application.yml and bootstrap.yml.
When I run mvn install -P test, text #env# in application.yml would be replaced by test.
How does it work?
Why it does't work for bootstrap.xml?
It works for application.yml because you are obviously using the Spring Boot Starter Parent. See the POM here: https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-starters/spring-boot-starter-parent/pom.xml
The magic part is the <resources> configuration within that parent POM. You see that the application config files are explicitly copied with filtering. That is why the maven-resources-plugin resolves placeholders in these files.
If you want to add more files to be handled like this you can add your own <resources> section to your POM and extend it by more file patterns.

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

Is it possible to use a maven property to activate a profile based upon a file?

I would like to download the JACOB dlls when they're not in my local repository.
As a consequence, I have those two profiles
<profile>
<id>use-jacob-dll</id>
<activation>
<file>
<exists>${settings.localRepository}/com/hynnet/jacob/1.18/jacob-1.18-x64.dll</exists>
</file>
</activation>
<dependencies>
<dependency>
<groupId>${jacob.groupId}</groupId>
<artifactId>jacob</artifactId>
<type>dll</type>
<classifier>x64</classifier>
<version>${jacob.version}</version>
</dependency>
</dependencies>
</profile>
<profile>
<id>download-jacob-dll</id>
<activation>
<file>
<missing>${settings.localRepository}/com/hynnet/jacob/1.18/jacob-1.18-x64.dll</missing>
</file>
</activation>
But, even when download-jacob-dll has accomplished its goal, a call to mvn help:active-profiles indicates the following
The following profiles are active:
- tests-for-eclipse (source: com.capgemini.admdt:kpitv:1.2.4-SNAPSHOT)
- download-jacob-dll (source: com.capgemini.admdt:kpitv:1.2.4-SNAPSHOT)
I suspect it is due to the fact that I use the ${settings.localRepository} in my activation property.
Question: Is it the cause of the failure? And if so, how can I activate my profile only when dependency is missing ?
Is it possible to use a maven property to activate a profile based upon a file?
No, as stated by the Maven documentation on profiles
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.
However, from the POM documentation we also get that
a given filename may activate the profile by the existence of a file, or if it is missing. NOTE: interpolation for this element is limited to ${basedir}, System properties and request properties.
Hence, indeed no Maven properties except ${basedir} are allowed.
And if so, how can I activate my profile only when dependency is missing?
By hardcoded path to the dependency or concerned file would be a solution, even though not portable like the solution you meant.
Alternatively you could use a request property as mentioned by the documentation above, thus need to configure the activation with a property which then must be passed from the command line (more portable but more fragile as well):
<activation>
<file>
<missing>${path}/com/hynnet/jacob/1.18/jacob-1.18-x64.dll</missing>
</file>
</activation>
Then invoke maven as following:
mvn clean install -Dpath=path_to_local_rep
The solution above could be reasonable in some contexts like Jenkins jobs.

read Maven variable from properties file using profile

I want to read a maven variable for configure a build plugin from a properties file. It's not needed in and further project files e.g. context files.
1) made a profile (it works, can use mvn ... -P private)
<profile>
<id>private</id>
<properties>
<env>private</env>
</properties>
</profile>
2) created the filter file with this content (it works)
foo.path=/home/foo/path
3) try to configure the plugin (does not work)
<build>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>foo-plugin</artifactId>
<version>${foo-plugin.version}</version>
<configuration>
<!--<fooPath>home/foo/path></fooPath> that works -->
<fooPath>${foo.path}</fooPath> <!--works not -->
</configuration>
...
</build>
Thx a lot
The name of your property is 'env' but you don't use env anywhere in your configuration.
When Maven docs mention "filter files" they usually mean a file used when processing resources (i.e. copying resources from /src/main/resources to target/classes). As far as I know the properties in those files aren't used for plugin configuration out-of-the-box. I have used the Codehaus properties-maven-plugin:read-project-properties goal do do what you are attempting. Make sure you bind the goal to the lifecycle before any plugins that need the properties for config.
Also, see this answer; you may load properties used to configure other plugins, but not to configure core Maven project elements.

I can't get maven to use properties defined in ~/.m2/settings.xml?

I am using ~/.m2/settings.xml to store a number of property names used throughout the pom.xml files in my project. If I make the XML invalid (by adding another < for example), maven immediately generates an error, saying that it cannot parse that file. If I leave the XML valid, settings in my appBeans.xml file do not pick of references to properties defined in settings.xml.
Has anyone experienced this problem? I am sort of at my wits end here.
Reflecting properties from Maven configurations works by resources filtering.
Make sure your settings.xml, project pom and the target xml file contain correct configurations and reside in correct places.
If I understood correctly, you want to store a property name and value in the settings.xml so the props can be used in your project files. I'll provide a working example:
Define a default profile and properties in settings.xml:
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<someProp>Value</someProp>
</properties>
</profile>
</profiles>
Define resource folder's filtering=true in pom.xml:
<build>
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
Define the property in the xml file (that resides in the src/main/resources folder):
...
<element>${someProp}</element>
...
After this you should see the filtered result e.g. in target/classes/appBeans.xml.
Bear in mind that if you're using Eclipse & m2eclipse or similar plugin, it probably won't start using the updated settings.xml without restarting Eclipse and it's automatic build will sometimes overwrite your files in the target folder. I'm talking from experience here :)
Maven properties do not get reflected in miscellaneous XML files.
If you add one of these properties to the <properties/> element of the specific pom that runs the specific plugin that reads allBeans.xml, does that work? I believe that it will not, and your problem will turn out to be adding to the <configuration/> for the plugin to pass the maven properties to it.
If you edit your question to show the plugin that processes appBeans.xml I can make this more specific.

Resources