Can't start with profiles in spring + maven + tomcat - java

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.

Related

maven profile overwrites test resources

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>.

Maven profile activation from windows system variable not working

I have the following maven profile configuration
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
<property>
<name>spring.profiles.active</name>
<value>dev</value>
</property>
</activation>
</profile>
<profile>
<id>test</id>
<activation>
<property>
<name>spring.profiles.active</name>
<value>test</value>
</property>
</activation>
</profile>
</profiles>
I have this in application.properties
spring.profiles.active=dev
So dev is my default for both spring and maven profiles.
I then have Windows system variable SPRING_PROFILES_ACTIVE set with a value of test to explicitly use the test profile.
which according to the documentation this should override the dev value in my properties file
http://docs.spring.io/spring-boot/docs/current/reference/html/howto-properties-and-configuration.html
69.5 Set the active Spring profiles
The Spring Environment has an API for this, but normally you would set
a System property (spring.profiles.active) or an OS environment
variable (SPRING_PROFILES_ACTIVE). E.g. launch your application with a
-D argument (remember to put it before the main class or jar archive):
$ java -jar -Dspring.profiles.active=production
demo-0.0.1-SNAPSHOT.jar
In Spring Boot you can also set the active profile in
application.properties, e.g.
spring.profiles.active=production
A value set this way is replaced by the System property or environment
variable setting, but not by the SpringApplicationBuilder.profiles()
method. Thus the latter Java API can be used to augment the profiles
without changing the defaults.
See Chapter 25, Profiles in the ‘Spring Boot features’ section for
more information.
Now when I run my Spring application it IS using the test profile in Spring, however the maven profile activation does not pick up on this and is still using the dev profile.
I have tried setting SPRING_PROFILES_ACTIVE as the name in the <property> element to make sure it wasn't a issue with the lowercase . version and the uppercase _ version but that didn't help.
It DOES work if I supply the variable when I run maven with -Dspring.profiles.active=test.
Any help is greatly appreciated.
edit: apparently this also doesn't work when I deploy a war to tomcat where catalina.properties contains spring.profiles.active=test. The same thing, Spring uses test but Maven is still stuck on dev.
How about activating the profile by using environment variable ?
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
<property>
<name>spring.profiles.active</name>
<value>dev</value>
</property>
</activation>
</profile>
<profile>
<id>test</id>
<activation>
<property>
<name>env.SPRING_PROFILES_ACTIVE</name>
<value>test</value>
</property>
</activation>
</profile>
</profiles>
Unfortunately, what you want to do is not possible. Profiles can only be activated from the command line or in some cases from the settings.xml. See this answer. This one includes links to JIRA issues discussing the challenges and what others have tried to make it work.
System properties are set on the command line.

Maven Profile reads data from Properties file

I have a Selenium project which uses Maven as a build tool and I want to read different environment details (protocol, domain, subdomain, etc) from a .properties file. Would it be possible to use Maven profiles in order to run my tests on different environments such as dev, staging, prod based on the profile which I am specifying when triggering the mvn command?
dev.properties:
protocol=http
domain=domain.com
subdomain=www
pom.xml:
<profiles>
<profile>
<id>prod</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>pre_prod</id>
</profile>
<profile>
<id>dev</id>
</profile>
</profiles>
mvn:
mvn clean test -Pdev
Data should then be retrieved in the java code using
System.getProperty("protocol");
System.getProperty("domain");
System.getProperty("subdomain");
Any help would be very much appreciated.
Thanks!
If you just want to read different properties files based on a command line argument, could you not just pass in a string for example -Denv=dev
Then in your properties reader class have it init the properties file based on System.getProperty("env");
Properties generalProperties = new Properties();
String generalPropertiesFileName = "data/"+
System.getProperty("env") + ".properties";
initProperties(generalProperties, generalPropertiesFileName);
Alternatively you can also pass properties from the command line to your POM in the same way -
<properties>
<property>
<protocol></protocol>
<domain></domain>
<subdomain></subdomain>
<property>
<properties>
And then these can be passed in from the command line as -Dprotocol=foo etc
Hope that helps?

How to use maven profile and overlays to build and package with specified project from multiple?

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. :-)

How to activate a pom.xml iff the os is not of a given family (eg. mac)?

From Maven's website:
...
<profiles>
<profile>
<id>default-tools.jar</id>
<activation>
<property>
<name>java.vendor</name>
<value>Sun Microsystems Inc.</value>
</property>
</activation>
<dependencies>
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>1.4.2</version>
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
</dependencies>
</profile>
</profiles>
...
tools.jar is already inclduded on Macs, embedded with classes.jar. Was there no way to specify !mac in the activation settings (except for listing every os except the mac) in the pom.xml, instead of always getting:
ERROR>warning: [path] bad path element ""/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/lib/tools.jar"": no such file or directory
You can use the '!' modifier in the os section of activation (tried and works with Maven 3.0.3). Uses the same algorithm as the enforcer plugin, described here.
<profiles>
<profile>
<id>not-mac</id>
<activation>
<os>
<family>!mac</family>
</os>
</activation>
<properties>
<!-- Define non-mac properties here -->
</properties>
</profile>
</profiles>
See this article for a more complete description of using tools.jar in Maven.
I found another method. Have the dependency in an "activeByDefault" profile. Have another profile (profile-2) which gets activated if the OS is mac. According to this the "activeByDefault" profiles get deactivated if any of the other profiles get activated. So if the OS is mac, profile-2 will get activated, which will deactivate the "activeByDefault" profile.

Categories

Resources