I am trying to setup an integration-test environment using Maven for my project but am getting the below error when I run the Compile goal.
[ERROR] Failed to execute goal
org.apache.maven.plugins:maven-resources-plugin:3.0.2:resources
(default-resources) on project mavenintegrationtest: Error loading
property file
'/Users/xxx/dev/poc/java/mavenintegrationtest/profiles/dev/config.properties'
-> [Help 1]
The error seems to be complaining that it cant find the config.properties file in that location which is correct. For some reason it has removed the "src/main/resources" bit from the file path.
So the correct full path is,
/Users/xxx/dev/poc/java/mavenintegrationtest/src/main/resources/profiles/dev/config.properties
but for some reason its removed src/main/resources and so is looking in,
/Users/xxx/dev/poc/java/mavenintegrationtest/profiles/dev/config.properties
Does anyone know whats causing this ?
My POM is as shown below and I get this error when I uncomment the following "filter" tag,
<filter>${basedir}/profiles/${build.profile.id}/config.properties</filter>
I've tried removing the ${basedir} statement and still get the same error.
<?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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.stackoverflow</groupId>
<artifactId>mavenintegrationtest</artifactId>
<version>1.0-SNAPSHOT</version>
<name>mavenintegrationtest</name>
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<filters>
<filter>${basedir}/profiles/${build.profile.id}/config.properties</filter>
</filters>
<resources>
<resource>
<filtering>true</filtering>
<directory>${basedir}/src/main/resources</directory>
</resource>
</resources>
</build>
<!-- Profile configuration -->
<profiles>
<!-- The configuration of the development profile -->
<profile>
<id>dev</id>
<!-- The development profile is active by default -->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<build.profile.id>dev</build.profile.id>
</properties>
</profile>
<!-- The configuration of the integration-test profile -->
<profile>
<id>integration-test</id>
<properties>
<build.profile.id>integration-test</build.profile.id>
</properties>
</profile>
</profiles>
</project>
The filter (link) element will parse your files and apply a content filter on them.
The profiles (link) element helps you define different environments for the build.
All of this as to do with your resources. These can be configuration files, or other type of files. If you filter then you can change the content of this files with other values - e.g. pom properties. When using profiles you can have different replacement properties for each environment.
You should move the profiles up in the tree for the default path, or add a configuration in your pom for the resource location.
The base dir is the folder containing your pom. You should have your profile folder here.
Also, here is some good information about profiles and its configurations.
Related
In my pom, I have two profiles.
test1
test2
Now I want my war name to change based on the activated profile.
Expected Result
When test1 profile is activated, war name should be prefix-test1.war.
When test1 and test2 are activated, war name should be prefix-test1-test2.war.
When no profile is activated, war name should be prefix.war.
My POM file ....
<?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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.sbill</groupId>
<artifactId>sbill-wrapper</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<packaging>war</packaging>
<artifactId>executable</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<profiles>
<profile>
<id>test1</id>
<properties>
<rp.build.warname>test1</rp.build.warname>
</properties>
</profile>
<profile>
<id>test2</id>
<properties>
<rp.build.warname>test2</rp.build.warname>
</properties>
</profile>
</profiles>
<build>
<finalName>prefix-${rp.build.warname}</finalName>
</build>
</project>
Right now if I run command mvn clean install the war name is prefix-null.war
. If I run command mvn clean install -P test1,test2 the war name is prefix-test2.war.
The result is different to what expected.
Firstly, to avoid showing null when no profiles, we can provide a default value for the property rp.build.warname, as mentioned in Setting default values for custom Maven 2 properties.
For the case running mvn clean install -P test1,test2, the war name is prefix-test2.war as the value of rp.build.warname is overridden, you may read How are conflicting properties resolved if multiple profiles are activated for more details.
In Order to have multiple values, we can use two properties(rp.build.warname1, rp.build.warname2) instead.
The following pom.xml includes the above changes
<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>
<parent>
<groupId>com.sbill</groupId>
<artifactId>sbill-wrapper</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<packaging>war</packaging>
<artifactId>executable</artifactId>
<!-- Provide default value here to avoid null in file name -->
<properties>
<rp.build.warname1/>
<rp.build.warname2/>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<profiles>
<profile>
<id>test1</id>
<properties>
<rp.build.warname1>-test1</rp.build.warname1>
</properties>
</profile>
<profile>
<id>test2</id>
<properties>
<rp.build.warname2>-test2</rp.build.warname2>
</properties>
</profile>
</profiles>
<build>
<finalName>prefix${rp.build.warname1}${rp.build.warname2}</finalName>
</build>
</project>
I know that it is possible to configure Decorators in the "beans.xml" file that is embedded in the EAR to be deployed.
The problem is that I use the same EAR for all the environments, and the set of properties or specific configurations are stored in some folder outside the package.
I need to determine if a Decorator will be used or not "external beans.xml" or some similar mechanism (something that is outside the EAR).
Any ideas?
Thank you very much.
Normally, this won't work - standard means of enablement are beans.xml for per-archive approach and #Priority for global enablement. There is nothing like "external beans.xml".
Although there is a way to enable it with extension. You need to set up an extension and observe AfterTypeDiscovery event. From there you can
make use of public List<Class<?>> getDecorators(); which returns MUTABLE list of decorators - so you can add your own into the list (in a form of a Class). That should enable it.
Another scenario you can use, is to utilize build-time inclusion and processing.
If you know before hand, what properties activate specific decorators at build-time, then you can use maven resources, together with system properties, to define additional resources to be filtered, thus:
<?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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompant</groupId>
<artifactId>my-project-id</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<some.kind.of.selector.properties>$basedir}/src/main/resources/development</some.kind.of.selector.properties>
</properties>
<build>
<resources>
<resource>
<directory>${some.kind.of.selector.properties}</directory>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
<profiles>
<profile>
<id>test</id>
<properties>
<some.kind.of.selector.properties>$basedir}/src/main/resources/test</some.kind.of.selector.properties>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<some.kind.of.selector.properties>$basedir}/src/main/resources/prod</some.kind.of.selector.properties>
</properties>
</profile>
</profiles>
</project>
The at build time, you can specify different beans.xml for every environment:
mvn clean install -Pprod
or even specify the property directly
mvn clean install -Dsome.kind.of.selector.properties=/path/to/additional/resources
I have a spring boot application where I want to package it according to the profile I am building with, for example when I issue profile x, I want maven to build as a jar; but when building with profile y, I want maven to build as a war.
I want something like:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0.0</version>
<package>${buildMethod}</package>
</project>
Where ${buildMethod} is the type of packaging.
This would be decided by executing a command i.e. mvn package -P buildProfile.
Maybe this would help:
<profiles>
<profile>
<id>war</id>
<properties>
<deploy.type>war</deploy.type>
</properties>
</profile>
<profile>
<id>jar</id>
<properties>
<deploy.type>jar</deploy.type>
</properties>
</profile>
</profiles>
And then just use this property placeholder ${deploy.type}.
You can easily add profiles, with a list of properties, to your pom file.
Build using:
mvn package - Builds a WAR by default (implicit)
mvn package -P deployWar - Builds a WAR
mvn package -P deployJar - Builds a JAR
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0.0</version>
<package>${deployment.type}</package>
<profiles>
<!-- This profile deploys the application as a WAR (default) -->
<profile>
<id>deployWar</id>
<properties>
<deployment.type>war</deployment.type>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<!-- This profile deploys the application as a JAR -->
<profile>
<id>deployJar</id>
<properties>
<deployment.type>jar</deployment.type>
</properties>
</profile>
</profiles>
</project>
I would like to configure a properties files depending on a profile, either ´dev´ or ´prod´, however the placeholders in the properties file are not replaced when executing the maven install goal.
Here is the pom file:
<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>abc.myproject</groupId>
<artifactId>myartifact</artifactId>
<packaging>war</packaging>
<version>0.1.0-SNAPSHOT</version>
<name>projectname</name>
<description>Site Description</description>
<url>http://www.myproject.abc</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven-war-plugin.version>2.4</maven-war-plugin.version>
<tomcat-deploy-path>output</tomcat-deploy-path>
</properties>
<dependencies>
// various dependencies
</dependencies>
<build>
<finalName>v${project.artifactId}#${project.version}</finalName>
<filters>
<filter>src/main/resources/profiles/${build.profile.id}/mongo.properties</filter>
</filters>
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>${maven-war-plugin.version}</version>
<configuration>
<outputDirectory>${tomcat-deploy-path}</outputDirectory>
<failOnMissingWebXml>true</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<build.profile.id>dev</build.profile.id>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<build.profile.id>prod</build.profile.id>
</properties>
</profile>
</profiles>
</project>
The placeholder mongo.properties file:
database.name=${database.name}
database.port=${database.port}
database.host=${database.host}
database.username=${database.username}
database.password=${database.password}
The profiles/dev/mongo.properties file:
database.name=mydatabase
database.port=27017
database.host=localhost
database.username=root
database.password=psw1
The directory structure is as follows:
> myproject
pom.xml
> src
> main
> java
> resource
> profiles
mongo.properties
> dev
mongo.properties
> prod
mongo.properties
> webapp
> test
I followed the instructions in this blog article: http://www.petrikainulainen.net/programming/tips-and-tricks/creating-profile-specific-configuration-files-with-maven/
I just tested your setup and it worked correctly: the file WEB-INF/classes/mongo.properties was correctly replaced.
The problem you are having revolves around the fact that you are outputting the final war inside a folder that is not under target. This is a very bad idea. Currently, the final WAR is generated inside the directory output, which corresponds to the property tomcat-deploy-path in your POM.
<tomcat-deploy-path>output</tomcat-deploy-path>
The big problem with such a setup is that running mvn clean will not delete that directory and subsequent builds won't override it, meaning the WAR will never be updated and you will keep an old obsolete WAR. I strongly suggest that you move this property under the Maven build directory, something like
<tomcat-deploy-path>${project.build.directory}/output</tomcat-deploy-path>
so that it is properly cleaned when running mvn clean.
As such, to resolve your problem, you should manually delete the folder output and rerun mvn clean install. It should generate a proper and new WAR.
Try using #..# instead of ${}, for example
database.name=#database.name#
For more info refer to: https://docs.spring.io/spring-boot/docs/1.4.x/reference/html/howto-properties-and-configuration.html
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>