Placeholder not being changed when deploying maven project to tomcat - java

I got maven project with pom.xml in which I replace placeholder in one of configuration files according to profile as follows:
<properties>
<mq-server.host>127.0.0.1</mq-server.host>
</properties>
<build>
<resources>
<resource>
<directory>src/main/resources/config</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<profiles>
<profile>
<id>staging</id>
<properties>
<mq-server.host>local.staging.com</mq-server.host>
</properties>
</profile>
</profiles>
When I build project using maven all doing fine on the other hand my project is Web project that is synchronizing with local tomcat via eclipse plugin and when I'm running project on tomcat using "play" button in eclipse, placeholder is not being changed. I wonder how I can fix it without adding special file just for developer.

Related

Maven profiles are not activating except default profile

I am working on a spring-boot application. I have two profiles inside my POM, but when I am trying the build the project using clean install -Pdev its not reflecting the change in application.properties, it'll only reflect when I am using 'activeByDefault' tag in one of the profile.
<profiles>
<profile>
<id>dev</id>
<properties>
<activatedProperties>dev</activatedProperties>
</properties>
</profile>
<profile>
<id>release</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<activatedProperties>release</activatedProperties>
</properties>
</profile>
</profiles>
If I am running clean install -Pdev I am getting this in my application.properties.
activatedProperties=#activatedProperties#
If I am setting the <activeByDefault>true</activeByDefault> then I'll get the value inside application.properties.
activatedProperties=release.
The frustration is I am not able to use other profiles.
Add in your application.properties
spring.profiles.active=#activatedProperties#
If Maven doesn't find the directory which contains your application.properties file in runtime, you need to setup the Maven Resources Plugin to filter the directory.
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
...
</build>
Or just add what profile you want to active in application.properties
spring.profiles.active=dev
NOTE: The Maven profile and the Spring profile are different things.

How to configure Maven profiles with different resources folders?

I'm trying to configure my application to have 2 build profiles: development and production. In order to do that, I created two subdirectories under the src/main/resources folder: src/main/resources/development and src/main/resources/production. Each subdirectory has its own .properties files.
<profiles>
<profile>
<id>development</id>
<build>
<resources>
<resource>
<directory>src/main/resources/development</directory>
</resource>
</resources>
</build>
</profile>
<profile>
<id>production</id>
<build>
<resources>
<resource>
<directory>src/main/resource/production</directory>
</resource>
</resources>
</build>
</profile>
</profiles>
I build the app with the command mvn install -P ${profile_here}
Maven copies the content of the folder related to the chosen profile to the WEB-INF/classes output directory, however the development and production folders are copied as well.
WEB-INF/classes
WEB-INF/classes/development
WEB-INF/classes/production
How can I solve this problem?
Thanks in advance.
The maven-war-plugin is rather limited when it comes to resources. However, you could use the maven-resources-plugin to include/exclude resources like described here: https://maven.apache.org/plugins/maven-resources-plugin/examples/include-exclude.html

Java Release and Debug properties files

I am writing a Java application which is almost ready for release, but I don't know how to create different .properties files for Debug and Release.
Let me clarify this for you.
I am storing the database host, username, password and other properties in the .properties files.
When I am writing and debugging the application these properties are configured to work with my development machine and database, but when the application is released they need to point to the release database and contain the release properties.
Is there any way to achieve this with Java and Maven?
I once did something similar, I wanted to have several resources packs in a Java webapp: one for IDE development, one for local (but outside IDE) development for graphic designers, and finally one for release, with all the packing controlled by Maven.
My solution is to declare several extra resources folders in the <build> node, and tell Maven which one to pick up using profiles (like #biziclop already suggested you); those folders are controlled through properties.
This is the POM I've used:
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<packaging>war</packaging>
<name>...</name>
<!-- My prerequisite was that when working in Eclipse no extra steps
should be required to make the IDE use the right configuration than
Configure -> Convert to Maven Project, so I didn't like having
default settings in a profile that must be enabled in Eclipse project
configuration -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<war-name>/</war-name>
<!-- These solve the problem: AFAICT, each <resource /> is added to the final POM,
so declaring a resources folder in a profile didn't exclude other resources
folders declared in the default (i.e. without profiles active) configuration.
So, the solution is to change what Maven brings in from each folder depending
on the profile currently active. What follows is the default, no-profile
active configuration. -->
<res.devel.includes>**/*</res.devel.includes>
<res.devel.excludes></res.devel.excludes>
<res.local.includes></res.local.includes>
<res.local.excludes>*</res.local.excludes>
<res.release.includes></res.release.includes>
<res.release.excludes>*</res.release.excludes>
</properties>
<build>
<resources><!-- Here I declare all the resources folders, so that they will all be shown in Eclipse. Property values drive what is included and excluded. -->
<resource><!-- This is the default Maven main resource directory -->
<directory>${basedir}/src/main/resources-local</directory>
<filtering>true</filtering>
<includes>
<include>${res.devel.includes}</include>
</includes>
<excludes>
<exclude>${res.devel.excludes}</exclude>
</excludes>
</resource>
<resource><!-- This is the resources directory for when the WAR is deployed on a local standalone Tomcan installation (useful for web pages editing) -->
<directory>${basedir}/src/main/resources-local</directory>
<filtering>true</filtering>
<includes>
<include>${res.local.includes}</include>
</includes>
<excludes>
<exclude>${res.local.excludes}</exclude>
</excludes>
</resource>
<resource><!-- This is the resource directory for when the WAR will be deployed -->
<directory>${basedir}/src/main/resources-release</directory>
<filtering>true</filtering>
<includes>
<include>${res.release.includes}</include>
</includes>
<excludes>
<exclude>${res.release.excludes}</exclude>
</excludes>
</resource>
</resources>
<plugins>
<!-- Plugins configurations -->
</plugins>
</build>
<dependencies>
<!-- Dependencies declarations -->
</dependencies>
<profiles><!-- Here are the profiles. When working in Eclipse no profile is active, so the resources will be taken only from src/main/resources (as per default properties values). -->
<profile>
<id>local</id><!-- This is for when the WAR is deployed on a local standalone Tomcat instance (i.e. outside of Eclipse) -->
<properties>
<war-name>ROOT</war-name>
<!-- The resources will be taken only from src/main/resources-local -->
<res.devel.includes></res.devel.includes>
<res.devel.excludes>*</res.devel.excludes>
<res.local.includes>*</res.local.includes>
<res.local.excludes></res.local.excludes>
<res.release.includes></res.release.includes>
<res.release.excludes>*</res.release.excludes>
</properties>
</profile>
<profile>
<id>release</id><!-- This is for when the WAR is deployed on the production server -->
<properties>
<war-name>ROOT</war-name>
<!-- The resources will be taken only from src/main/resources-release -->
<res.devel.includes></res.devel.includes>
<res.devel.excludes>*</res.devel.excludes>
<res.local.includes></res.local.includes>
<res.local.excludes>*</res.local.excludes>
<res.release.includes>*</res.release.includes>
<res.release.excludes></res.release.excludes>
</properties>
</profile>
</profiles>
</project>
You may get further details in my answer here.

How to specify in Maven extra source/resource folders so IDEs are aware of them?

I'm a Maven beginner, and after some trial and error, I managed to specify different properties files for the release WAR with respect to the development WAR (I tried to do it in the simplest way I could think of, but feel free to suggest any simpler solution).
So, during development, my database.properties and log4j.properties come from src/main/resources, while producing the release WAR they come from src/main/resources/release.
So far, so good.
The question is: since I'm working with Eclipse, is there a way to say, inside the POM, that the src/main/resources/release is a source folder too, so that Eclipse will list it under the other source folders in the Project Explorer, even when another developer imports the project inside his IDE (i.e. without adding that folder as a source folder manually)?
This is the relevant part of my POM:
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
...
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<war-name>/</war-name>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
...
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
...
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
...
</plugin>
</plugins>
</build>
<dependencies> ... </dependencies>
<profiles>
<profile>
<id>release</id>
<properties>
<war-name>ROOT</war-name>
</properties>
<build>
<resources><!-- Replace Maven default resources directory (this could probably be achieved with a property)-->
<resource>
<filtering>true</filtering>
<directory>${basedir}/src/main/resources/release</directory>
<includes>
<include>*</include>
</includes>
</resource>
</resources>
</build>
</profile>
</profiles>
<build>
...
< sourceDirectory > src/main/java </ sourceDirectory >
< testSourceDirectory > src/test/java </ testSourceDirectory >
< resources >
< resource >
< directory > src/main/resources </ directory >
</ resource >
</ resources >
< testResources >
< testResource >
< directory > src/test/resources </ directory >
</ testResource >
</ testResources >
...
</build>
You can specify the profile that eclipse should run maven in...
Right click on project, select Maven, and include the profiles you can eclipse to work under.
Your config should be picked up by eclipse when you do a maven update project (i.e. eclipse should recognise the new source folders) once you've changed the profile.
Here's how I did it.
Basically, I declare all the resources folders I want to see in Eclipse in the default configuration (adding them in each profile didn't work since when a profile is active, the <resources /> node is appended to the final POM instead of (as I thought) replacing the existing one); then I tell Maven from which folder to copy the resources using properties, whose values are driver by the active profile.
Any comment is, of course, very much appreciated!
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<packaging>war</packaging>
<name>...</name>
<!-- My prerequisite was that when working in Eclipse no extra steps
should be required to make the IDE use the right configuration than
Configure -> Convert to Maven Project, so I didn't like having
default settings in a profile that must be enabled in Eclipse project
configuration -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<war-name>/</war-name>
<!-- These solve the problem: AFAICT, each <resource /> is added to the final POM,
so declaring a resources folder in a profile didn't exclude other resources
folders declared in the default (i.e. without profiles active) configuration.
So, the solution is to change what Maven brings in from each folder depending
on the profile currently active. What follows is the default, no-profile
active configuration. -->
<res.devel.includes>**/*</res.devel.includes>
<res.devel.excludes></res.devel.excludes>
<res.local.includes></res.local.includes>
<res.local.excludes>*</res.local.excludes>
<res.release.includes></res.release.includes>
<res.release.excludes>*</res.release.excludes>
</properties>
<build>
<resources><!-- Here I declare all the resources folders, so that they will all be shown in Eclipse. Property values drive what is included and excluded. -->
<resource><!-- This is the default Maven main resource directory -->
<directory>${basedir}/src/main/resources-local</directory>
<filtering>true</filtering>
<includes>
<include>${res.devel.includes}</include>
</includes>
<excludes>
<exclude>${res.devel.excludes}</exclude>
</excludes>
</resource>
<resource><!-- This is the resources directory for when the WAR is deployed on a local standalone Tomcan installation (useful for web pages editing) -->
<directory>${basedir}/src/main/resources-local</directory>
<filtering>true</filtering>
<includes>
<include>${res.local.includes}</include>
</includes>
<excludes>
<exclude>${res.local.excludes}</exclude>
</excludes>
</resource>
<resource><!-- This is the resource directory for when the WAR will be deployed -->
<directory>${basedir}/src/main/resources-release</directory>
<filtering>true</filtering>
<includes>
<include>${res.release.includes}</include>
</includes>
<excludes>
<exclude>${res.release.excludes}</exclude>
</excludes>
</resource>
</resources>
<plugins>
<!-- Plugins configurations -->
</plugins>
</build>
<dependencies>
<!-- Dependencies declarations -->
</dependencies>
<profiles><!-- Here are the profiles. When working in Eclipse no profile is active, so the resources will be taken only from src/main/resources (as per default properties values). -->
<profile>
<id>local</id><!-- This is for when the WAR is deployed on a local standalone Tomcat instance (i.e. outside of Eclipse) -->
<properties>
<war-name>ROOT</war-name>
<!-- The resources will be taken only from src/main/resources-local -->
<res.devel.includes></res.devel.includes>
<res.devel.excludes>*</res.devel.excludes>
<res.local.includes>*</res.local.includes>
<res.local.excludes></res.local.excludes>
<res.release.includes></res.release.includes>
<res.release.excludes>*</res.release.excludes>
</properties>
</profile>
<profile>
<id>release</id><!-- This is for when the WAR is deployed on the production server -->
<properties>
<war-name>ROOT</war-name>
<!-- The resources will be taken only from src/main/resources-release -->
<res.devel.includes></res.devel.includes>
<res.devel.excludes>*</res.devel.excludes>
<res.local.includes></res.local.includes>
<res.local.excludes>*</res.local.excludes>
<res.release.includes>*</res.release.includes>
<res.release.excludes></res.release.excludes>
</properties>
</profile>
</profiles>
</project>

how to manage a project which contains files specific to different OS?

we have a project which initially was developed to run on a linux platform, we want to customize it and use it under windows platform. It is hosted on github. Any advice on how to manage files that are shared between the two platforms but have some specificity for each one. for example configuration files that contains paths, environment variables and the like.
thanks for suggestion.
Since you have tagged maven here is the solution, use profiles to differentiate between linux and windows.
<profiles>
<profile>
<id>linux</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<envName>linux</envName>
</properties>
</profile>
<profile>
<id>windows</id>
<properties>
<envName>windows</envName>
</properties>
</profile>
</profiles>
<build>
<outputDirectory>${project.basedir}/target/classes</outputDirectory>
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
<resources>
<resource>
<directory>${basedir}/src/main/java</directory>
<includes>
<include>**/*.class</include>
</includes>
</resource>
<resource>
<targetPath>${project.basedir}/target/classes/configurations</targetPath>
<directory>${basedir}/src/main/resources/configurations/${envName}</directory>
</resource>
</resources>
<plugins>
</build>
Say suppose you have some configuration files specific to OS. and when you want to build based on the enivronment you want the file to copied to configurations directory inside class, the above code snippet copies that. For that to work you need to create 2 directories inside src/main/resoruces/configurations/linux and src/main/resources/configurations/windows. when you run maven you need to use profile like mvn package -Plinux or mvn package -Pwindows.

Categories