I'm trying to make maven profiles which would use two difference DBMS. DBMS configs are stored in maven profiles. Web App gets settings from file connection.properties in src/main/resources. There is also a similar file with same title connection.properties in src/test/resources and this file should be uploaded only during test lyfecycle maven. Then spring core uses the DBMS connection settings specified in connection.properties.
I have problem with maven profile which overwrites resources such as src/test/resources/connection.properties on src/main/resources/connection.properties from test directory when test lifecycle maven is running.
<profile>
<id>profile-postgres</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<database.driver_class_name>org.postgresql.Driver</database.driver_class_name>
<database.url>jdbc:postgresql://127.0.0.1:5432/bulls_and_cows</database.url>
<database.username>postgres</database.username>
<database.password>postgres</database.password>
<jpa.show_sql>true</jpa.show_sql>
<jpa.generate_ddl>true</jpa.generate_ddl>
<jpa.database>POSTGRESQL</jpa.database>
<jpa.database_platform>org.hibernate.dialect.PostgreSQL95Dialect</jpa.database_platform>
<jpa.hibernate.hbm2ddl.auto>validate</jpa.hibernate.hbm2ddl.auto>
<jpa.hibernate.format_sql>false</jpa.hibernate.format_sql>
<h2.scope>test</h2.scope>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.1</version>
</dependency>
</dependencies>
</properties>
</profile>
<profile>
<id>profile-h2</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<database.driver_class_name>org.h2.Driver</database.driver_class_name>
<database.url>jdbc:h2:mem:h2db;DB_CLOSE_DELAY=-1</database.url>
<database.username>sa</database.username>
<database.password>sa</database.password>
<jpa.show_sql>true</jpa.show_sql>
<jpa.generate_ddl>true</jpa.generate_ddl>
<jpa.database>H2</jpa.database>
<jpa.database_platform>org.hibernate.dialect.H2Dialect</jpa.database_platform>
<jpa.hibernate.hbm2ddl.auto>create-drop</jpa.hibernate.hbm2ddl.auto>
<jpa.hibernate.format_sql>false</jpa.hibernate.format_sql>
<h2.scope>compile</h2.scope>
</properties>
</profile>
</profiles>
This profile overwrites my connection.properties from src/test/resources on src/main/resources.
connection.properties from src/test/resources
database.driver_class_name=org.h2.Driver
database.url=jdbc:h2:mem:h2db;DB_CLOSE_DELAY=-1
database.username=sa
database.password=sa
connection.properties from src/main/resources
database.driver_class_name=${database.driver_class_name}
database.url=${database.url}
database.username=${database.username}
database.password=${database.password}
I wrote testResources tag in build tag of root pom file and in build tag of profile tag such as
<testResources>
<testResource>
<directory>${project.basedir}/src/test/resources</directory>
<filtering>true</filtering>
</testResource>
</testResources>
But instead connection.properties from src/main/resources was always used in test lifecycle of maven.
My old failed build where I used profiles from https://travis-ci.org/WeDism/BullsAndCows/builds/449051809.
My repo with master branch https://github.com/WeDism/BullsAndCows/blob/master/pom.xml.
My repo with with_profiles_h2_postgres branch https://github.com/WeDism/BullsAndCows/blob/with_profiles_h2_postgres/pom.xml
Profile profile-postgres should be main such as activeByDefault = true
For the fix this problem I changed property names such as
<database.driver_class_name> to <database.driver_class_name.pom>.
Related
In pom.xml, I define a property:
<profile>
<id>local</id>
<properties>
<build.profile.id>local</build.profile.id>
<serverBaseUrl>http://127.0.0.1:8080</serverBaseUrl>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
And the serverBaseUrl was referenced in file application-email.xml:
<bean id="MailService" class="someclass">
<property name="aurl" value="${serverBaseUrl}"/>
</bean>
I expect that, when running test, using IntelliJ IDEA or using Maven test, ${serverBaseUrl} can be pick up from pom.xml automatically. However, it does not work like what I expect.
When not running test, the thing works exactly what I expect.
What's the problem here? Does maven or IntelliJ IDEA won't pick up profile properties when running test by default? How can I pick up profile's properties when I running the test?
Currently, I have a workaround: Define serverBaseUrl=xxx in config.properties and the property is picked up. This is a little ugly what I want to avoid.
This is more like a shot in the dark, I could not test it.
Add the resources tag in the build section of your pom.xml:
<build>
.....
<testResources>
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
<includes>
<include>application-email.xml</include>
</includes>
</testResource>
</testResources>
....
</build>
I suppose your application-email.xml is inside src/test/resources folder.
I need to use profiles with spring. I use local Tomcat.
There is maven project, so, in pom.xml I added:
<profiles>
<profile>
<id>dev</id>
<activation>
<property>
<name>spring.profiles.active</name>
<value>dev</value>
</property>
</activation>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
</dependencies>
</profile>
<profile>
<id>at1</id>
<activation>
<activeByDefault>true</activeByDefault>
<property>
<name>spring.profiles.active</name>
<value>at1</value>
</property>
</activation>
</profile>
</profiles>
and in application.properties added spring.profiles.active=${activatedProperties}
note: spring.profiles.active=#activatedProperties# tried already too
and there is two files application-at1.properties and application-dev.properties
When build war with -Dspring.profiles.active=dev there is error message - params from this files not found.
My tomcat customizations are:
Can't tell exactly where you are but seems to me that you're using a property place holder, Spring Boot is not picking up a profile because the placeholder actually has no value.
You can configure this in the following way:
Using Property Placeholders:
application.properties
spring.profiles.active=${activatedProperties}
pom.xml
<property>
<name>activatedProperties</name>
<value>dev</value>
</property>
Just specify the runtime argument
Remove property from pom.xml and adjust your application.properties with some default value or don't specify it at all
spring.profiles.active=at1 #you can remove this line if you want.
Then run-war with argument -Dspring.profiles.active=dev
Working with Maven Profiles
You can run maven with a -P dev to make sure that the goal is executed with the correct profile.
I have to build a war file using maven to include jars conditionally,
each jar is created by a seperate maven project which deploys jar to nexus(our organisations remote) repository
Eg : I have jars like these core.jar,reward.jar,payment.jar,domains.jar so on
I need to build a final war based on conditions(environmnet) to include above jars
Combination of final war(w1)
w1.war : core.jar,domains.jar
w1.war : core.jar,domains.jar,rewards.jar(Any way to specify to include this jar if rewards is applicable)
The Maven WAR Plugin allows you to include/exclude JARs. For example:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<packagingExcludes>
WEB-INF/lib/excluded.jar
</packagingExcludes>
<packagingIncludes>
WEB-INF/lib/included.jar
</packagingIncludes>
</configuration>
</plugin>
You can associate the inclusions/exclusions with a condition by using profiles. For example, let the WAR plugin use properties (${excludedResources}, ${includedResources}) ...
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<packagingExcludes>
${excludedResources}
</packagingExcludes>
<packagingIncludes>
${includedResources}
</packagingIncludes>
</configuration>
</plugin>
... and define values for those properties via profiles:
<profiles>
<profile>
<id>prod</id>
<properties>
<excludedResources>WEB-INF/lib/a.jar,WEB-INF/lib/b.jar</excludedResources>
<includedResources>WEB-INF/lib/c.jar</includedResources>
</properties>
</profile>
<profile>
<id>tst</id>
<properties>
<excludedResources>WEB-INF/lib/x.jar,WEB-INF/lib/y.jar</excludedResources>
<includedResources>WEB-INF/lib/z.jar</includedResources>
</properties>
</profile>
</profiles>
So, you can use the Maven WAR Plugin's built-in ability to tweak the WAR contents and you can make these tweaks conditional by using Maven profiles.
You can try to use profiles capabilities in maven. Each dependency can be included into its own profile block e.g. domains will be included only if you switch this profile on and services - by services profile.
At the same time you can identify common jars through the common dependency block (in our case core.jar will be common)
<?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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.stackoverflow</groupId>
<artifactId>conditional-war</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>War Which Includes Jar By Conditions</name>
<!-- Common dependency block which will be always included -->
<dependencies>
<dependency>
<groupId>com.stackoverflow</groupId>
<artifactId>core</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<profiles>
<!-- Profile for domains jars. Will be included by
profile\condition "domains" -->
<profile>
<id>domains</id>
<activation>
<property>
<name>domains</name>
</property>
</activation>
<dependencies>
<dependency>
<groupId>com.stackoverflow</groupId>
<artifactId>domains</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</profile>
<!-- Profile for domains jars. Will be included by
profile\condition "services" -->
<profile>
<id>services</id>
<activation>
<property>
<name>services</name>
</property>
</activation>
<dependencies>
<dependency>
<groupId>com.stackoverflow</groupId>
<artifactId>services</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</profile>
</profiles>
</project>
Command line for the activation can be following:
By this command line will be included core.jar and domains.jar
mvn clean install -Pdomains
In such case war will include core.jar and services.jar
mvn clean install -Pservices
And finally by this command line will be included all the jars
mvn clean install -Pdomains,services
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 one web project called MyWebProject which having sub modules also and packaging as POM, I have other two simple java project called SimpleJavaProject1 and SimpleJavaProject2 which having packaging as JAR.
I am having dependency for both in web peoject. So I have to use Maven Profile and Overlays such way, that when I will build and package my web project with profile JavaProject1 then web project includes SimpleJavaProject1 in its war and when I said JavaProject2 then it should include SimpleJavaProject2. And it should use Overlays only for specified java project.
Can I use Overlays in Profile?
Please suggest some idea if any...
I'm not familiar with overlays, but hopefully this approach will work for them too.
Typically one solves this sort of problem by defining a property in your parent POM, based on the profile:
<profiles>
<profile>
<id>JavaProject1</id>
<properties>
<java.project>SimpleJavaProject1</java.project>
<java.project.version>1.1</java.project.version>
</properties>
</profile>
<profile>
<id>JavaProject2</id>
<properties>
<java.project>SimpleJavaProject2</java.project>
<java.project.version>1.2</java.project.version>
</properties>
</profile>
</profiles>
Then use this property when you define your dependency (and hopefully your overlays too):
<dependency>
<groupId>com.foo</groupId>
<artifactId>${java.project}</artifactId>
<version>${java.project.version}</version>
</dependency>
Got it...referring #Duncan answer I have tried following and its worked. :-)
Following are my Profiles,
<profile>
<id>JavaProject1</id>
<properties>
<roject.groupId>mygroupId</project.groupId>
<roject.artifactId>myartifactId</project.artifactId>
<roject.version>${myversion}</project.version>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>JavaProject2</id>
<properties>
<roject.groupId>mygroupId</project.groupId>
<roject.artifactId>myartifactId</project.artifactId>
<roject.version>${myversion}</project.version>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
And I have added Overlays in war plugin as follows,
<overlays>
<overlay>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<type>jar</type>
<targetPath>WEB-INF/classes</targetPath>
</overlay>
</overlays>
It worked successfully. :-)