Reputation: 21984
I am in the process of migrating an Application from Ant to Maven. There are two kinds of environment, this application can be deployed to. One configuration is called Local and the other caller dev, and hence naturally there are two ant targets. Each of ant targets, copies resources from two different folders and makes it part of the final war file.
How do I mimic this behavior in maven? I was thinking of passing a parameter at build time and based on this parameter, we can use maven resources plugin to copy the corresponding folder. Something like this.
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>${local}/**</exclude>
</excludes>
</resource>
</resources>
Am I in the right path? If yes, how do I substitute "local" at run time? Also, I am doing a complement operation, if we want to build for Dev, then I am excluding local and vice versa. Is there a better way to handle this?
Also if I use this method, the target war, has the entire folder copied to it. How can i configure maven to only copy the folder contents not the entire folder.
Upvotes: 0
Views: 4086
Reputation: 14951
When copying resources, Maven will apply the include/exclude pattern to the <directory>
value defined, and maintain the path structure from that directory down. There isn't any equivalent to ant's flattenmapper
that I've been able to find.
For the rest, consider Maven build profiles. You define profiles that contain the config you want to change at build time, then activate the right profile from the command line. With the config shown below, the command
mvn -Dtarget.env=local process-resources
would copy files from /src/main/resources/local
into target/classes
. Since 'local' is included in the resource's directory
element, it will not appear in the path for the copied resources.
<profiles>
<profile>
<id>local</id>
<activation>
<property>
<name>target.env</name>
<value>local</value>
</property>
</activation>
<properties>
<resource.dir>local</resource.dir>
</properties>
</profile>
<!-- add a similar profile for dev -->
</profiles>
<resources>
<resource>
<directory>src/main/resources/${resource.dir}</directory>
<filtering>true</filtering>
</resource>
</resources>
You can do a lot more with profiles that what I showed here. I hope this gets you started even if it doesn't solve your whole use case.
Upvotes: 2
Reputation: 97359
The best thing i can recommend is to create a structure like the following (only with the properties file):
.
|-- pom.xml
`-- src
|-- main
| |-- java
| |-- resources
| |-- environment
| | |-- test
| | | `-- database.properties
| | `-- production
| | `-- database.properties
| `-- webapp
Create a assembly descriptor like the following to use in combination with the maven-assembly-plugin for each environment one:
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>test</id>
<formats>
<format>war</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<unpack>true</unpack>
<useProjectArtifact>true</useProjectArtifact>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<outputDirectory>WEB-INF</outputDirectory>
<directory>${basedir}/src/main/environment/test/</directory>
<includes>
<include>**</include>
</includes>
</fileSet>
</fileSets>
</assembly>
And finally you need an execution for each environment:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>test</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>${project.basedir}/src/main/assembly/test.xml</descriptor>
</descriptors>
</configuration>
</execution>
<execution>
<id>production</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>${project.basedir}/src/main/assembly/production.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
The result will be to have via a single build two war files which have been configured for production and the other for development.
Upvotes: 1