Activate Spring Boot profile with Maven Profile - spring-boot

I use the solution https://stackoverflow.com/a/42391322/1681932 to activate Spring Boot profile.
It works well in Spring Boot 2.5.0.
Now I want to upgrade to Spring Boot 2.6.6 in my new project. But the solution fails.
application.properties
spring.profiles.active=#spring.profiles.active#
the console show:
The following profiles are active: #spring.profiles.active#
it seems that the notation #spring.profiles.active# is not replaced, it should be something like dev, prod.
Update:
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.6</version>
<relativePath/>
</parent>
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<spring.profiles.active>dev</spring.profiles.active>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<spring.profiles.active>prod</spring.profiles.active>
</properties>
</profile>
</profiles>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
...
</plugins>
</build>
application.properties
spring.profiles.active=#spring.profiles.active#
## other properties
application-dev.properties
## dev related properties
application-prod.properties
## prod related properties
IDEA output
2022-04-19 19:28:45.377 INFO 8360 --- [ main] c.c.a.MyApplication : Starting MyApplication using Java 18 on macdeMac-mini.lan with PID 8360 (/Users/mac/proj/MyApplication/target/classes started by mac in /Users/mac/proj/MyApplication)
2022-04-19 19:28:45.381 INFO 8360 --- [ main] c.c.a.MyApplication : The following 1 profile is active: "#spring.profiles.active#"
If I change 2.6.6 into 2.5.0 in pom.xml, everything works well.

Related

Spring boot change pom configuration with active profile

I was trying to change configuration of the pom based on the active profile (dev, test, qa, prod). but every time it was calling the default one (prod)
I have given the profile info in VM arguments in intellij
arguments : -Dspring.profiles.active=dev
Decleration (in POM.xml)
<profiles>
<profile>
<id>dev</id>
<properties>
<currentRegion>run build_dev</currentRegion>
</properties>
</profile>
<profile>
<id>test</id>
<properties>
<currentRegion>run build_test</currentRegion>
</properties>
</profile>
<profile>
<id>qa</id>
<properties>
<currentRegion>run build_qa</currentRegion>
</properties>
</profile>
<profile>
<id>prod</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<currentRegion>run build_prod</currentRegion>
</properties>
</profile>
</profiles>
Usage(in POM.xml)
<build>
<plugins>
<plugin>
<executions>
<execution>
<configuration>
<arguments>${currentRegion}</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Every time, this is retuning run build_prod (the default one)
Actually i have combined the spring boot and angular for some testing purpose and i want to run the angular on environment with different environment.ts file , when i hardcode the arguments in pom like run build_dev/test it works file , i want to automate it arguments based on the active profile .
Any Suggestions/Solution is highly appreciated.

Spring Boot Not Resolving Properties Variable When Using spring-boot:run

This was working for me and I'm not sure what changed.. I have my spring boot profile configured to be set based on a maven profile. The basics:
application.properties:
spring.profiles.active=#environment#
pom.xml:
<profiles>
<profile>
<id>development</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<environment>development</environment>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</profile>
<profile>
<id>production</id>
<properties>
<environment>production</environment>
</properties>
</profile>
</profiles>
When I run mvn clean package -Pdevelopment I see the line The following profiles are active: development.
Yet when I run mvn spring-boot:run -Pdevelopment I see the line The following profiles are active: #environment#.
Using the spring-boot:run command seems to not be able to resolve application property variables based on maven environment variables. Anyone know why? I tried adjusting the spring starter version without success.
According to the docs, you could tune the profiles to enable when running the application as follows:
$ mvn spring-boot:run -Dspring-boot.run.profiles=development
If not, try to comment your "spring.profiles.active" property in application.properties, that should work!
See also this thread.
Based on this tip in the docs, I added a configuration to my spring-boot-maven-plugin which broke this functionality:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<addResources>true</addResources>
</configuration>
</plugin>
Removing the addResources configuration restores the property expansion behavior.

exclude data.sql from Spring boot jar

I am trying to exclude my data.sql and schema.sql from the Spring boot application jar.
So far I have tried several options but they do not seem to work. This is my POM configuration.
<profiles>
<profile>
<id>dev</id>
<properties>
<activatedProperties>dev</activatedProperties>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>prod</id>
<properties>
<activatedProperties>prod</activatedProperties>
</properties>
<build>
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
<excludes>
<exclude>data.sql</exclude>
<exclude>schema.sql</exclude>
</excludes>
</resource>
</resources>
</build>
</profile>
</profiles>
Spring Boot enables it by default and loads SQL from the standard locations schema.sql and data.sql.If you want to disable this you can try,
spring.datasource.initialize=false
in application.properties or if you want to change default scheme or data scripts locations you can do it with,
spring.datasource.schema=
spring.datasource.data=
You can write this annotation on top of your test method
#TestPropertySource(locations = "classpath:application-test.properties")
Your application-test.properties should have something like this
spring.datasource.data=classpath:/database/seed.sql

Maven Profile Variable web project not working

I´ve got a modular maven project that contains 3 modules. In one of those (WEB), the profile variable is not being recognized as an environment variable, but it takes que real name of it, as shown below:
<Principal POM>
<Module App-core>
<Module ejb>
<Module web>
At the principal POM, there are 3 profiles thas have the same profile propertie with distinct values:
<profile1>
<environment>value1</environment>
<profile2>
<environment>value2</environment>
<profile3>
<environment>value3</environment>
That variable is used as classifier variable for dependencies, as below:
<dependency>
<groupId>com.test</groupId>
<artifactId>app-core</artifactId>
<version>1.0.0</version>
<classifier>${environment}</classifier>
</dependency>
At maven compile phase, only at Web Project, it doen´t change the variable name with the variable value.
Any help?
The tags profile1 profile2 profile3 don't enable the replacing property. To do this you have change your parent pom in this way
<project>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<profiles>
<profile>
<id>profile1</id>
<properties>
<environment>value1</environment>
</properties>
</profile>
<profile>
<id>profile2</id>
<properties>
<environment>value2</environment>
</properties>
</profile>
<profile>
<id>profile3</id>
<properties>
<environment>value2</environment>
</properties>
</profile>
</profiles>
</project>
Now you have to run mvn install -P profile1 yourProjectName
I've resolved the issue.
I've replicated the dependencies into profiles. I had multiples dependencies
This is the code to the profile1
<profile>
<id>profile1</id>
<properties>
<environment>value1</environment>
</properties>
<dependency>
<groupId>com.test</groupId>
<artifactId>app-core</artifactId>
<version>1.0.0</version>
<classifier>${environment}</classifier>
</dependency>
</profile>
This is the code to the profiles2
<profile>
<id>profile2</id>
<properties>
<environment>value2</environment>
</properties>
<dependency>
<groupId>com.test</groupId>
<artifactId>app-core</artifactId>
<version>1.0.0</version>
<classifier>${environment}</classifier>
</dependency>
</profile>
And this the code is to the profile3
<profile>
<id>profile3</id>
<properties>
<environment>value3</environment>
</properties>
<dependency>
<groupId>com.test</groupId>
<artifactId>app-core</artifactId>
<version>1.0.0</version>
<classifier>${environment}</classifier>
</dependency>
</profile>

How to configure maven to use different log4j.properties files in different environments

I want to be able to use different log4j configuration for different environments.
In my development environment, I want to use log4j.properties (A). But when I build in Maven for the production environment, I want to use log4j.properties (B).
Please tell me how to configure this in my pom.xml?
You can use profiles to achieve the desired behavior:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>log4j</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>output_directory</outputDirectory>
<resources>
<resource>${log4j.file}</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<log4j.file>path_to_file_A</log4j.file>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<log4j.file>path_to_file_B</log4j.file>
</properties>
</profile>
</profiles>
1. in your project add 3 folders :
Your Project\src\main\resources\
\A > log4j.properties
\B > log4j.properties
\Default > log4j.properties
2. in pom.xml
<properties>
<param>Default</param>
</properties>
<build>
<resources>
<resource>
<directory>src/main/resources/${param}</directory>
</resource>
</resources>
</build>
3.
- if : mvn clean install : classpath => log4j.properties(Default)
- if : mvn clean install -Dparam=A : classpath => log4j.properties(A)
- if : mvn clean install -Dparam=B : classpath => log4j.properties(B)
> much better than using profiles is more extensible without touching the pom
You don't need the maven-resources-plugin if you have a simple environment.
In this example, log4j.properties B is the file you use for production and is in the directory src/main/java and log4j.properties A is the file you use for development and is in the directory /Users/junger/.m2/.
In your pom.xml:
<properties>
<log4j.properties.directory>src/main/java</log4j.properties.directory>
</properties>
<build>
<resources>
<resource>
<directory>${log4j.properties.directory}</directory>
<includes>
<include>log4j.properties</include>
</includes>
</resource>
</resources>
</build>
Now, in your /Users/junger/.m2/settings.xml (create one if it doesn't exist):
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<log4j.properties.directory>/Users/devuser/.m2/</log4j.properties.directory>
</properties>
</profile>
</profile>
By using this method, each developer can have a different log4j.properties directory and you keep your pom.xml clean.
Simplest way for me,
Define a system variable ENV and set its value _dev for your development env.
Where you refer this file use like this log4j${ENV}.properties
So,
In production it simply use log4j.xml and for your dev log4j_dev.xml
In order to prevent problems it would be better to create also ENV variable for production as _pro so for production log4j_pro.xml, for dev log4j_dev.xml will be used.
I believe that relying on different files than copying resource is better practice.
There is a very simple solution good for small projects with jar packaging (I haven't tested it on war packaged projects). The only disadvantage is that you have to duplicate all resources, but if your only resource is log4j.properties this is not a problem.
If you have a directory tree like this:
...
You should have the following pom:
<build>
<finalName>${project.artifactId}</finalName>
<sourceDirectory>src/</sourceDirectory>
<resources>
<resource>
<directory>${resources.path}</directory>
</resource>
</resources>
</build>
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<resources.path>resources/prod</resources.path>
</properties>
</profile>
<profile>
<id>dev</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<resources.path>resources/dev</resources.path>
</properties>
</profile>
</profiles>
Then when you use dev profile log4j.properties from resources/dev is used. When you use any other profile or no profile at all then log4j.properties from resources/prod is used. So your *.jar should look like this:
Of course if you have different resources location, for example main/java/resources/..., you should specify it instead of resources/...
To some extent you can reference environment variables inside a log4j.properties to add environment dependent behavior.
e.g.
log4j.rootLogger=${rootLoggerLevel}, ${appender}

Resources