Maven Resources plugin
Maven Resources plugin example from http://maven.apache.org/plugins/maven-resources-plugin/
- Specifying a character encoding scheme
A character encoding scheme such as ASCII, UTF-8 or UTF-16 can be chosen to be used for the reading and writing of files.
For example, if we want to specify that the character encoding scheme be UTF-8, we would simply have to modify the POM.
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<configuration>
...
<encoding>UTF-8</encoding>
...
</configuration>
</plugin>
</plugins>
...
</build>
...
</project>
-
Specifying resource directories
By default, Maven will look for your project's resources under src/main/resources.
Project
|-- pom.xml
`-- src
`-- main
`-- resources
However, all your resources may not be in src/main/resources. Thus, you'd have to specify those directories by adding the following to your POM.
<project>
...
<build>
...
<resources>
<resource>
<directory>[your folder here]</directory>
</resource>
</resources>
...
</build>
...
</project>
So if your resources resides in src/my-resources
Project
|-- pom.xml
`-- src
`-- my-resources
you can specify that directory by doing the following:
...
<resources>
<resource>
<directory>src/my-resources</directory>
</resource>
</resources>
...
Furthermore, you can have several directories by adding multiple <resource> elements:
<resources>
<resource>
<directory>resource1</directory>
</resource>
<resource>
<directory>resource2</directory>
</resource>
<resource>
<directory>resource3</directory>
</resource>
</resources>
- Filtering
Variables can be included in your resources. These variables, denoted by the ${...} delimiters, can come from the system properties, your project properties, from your filter resources and from the command line.
For example, if we have a resource src/main/resources/hello.txt containing
Hello ${name}
And a POM like this
<project>
...
<name>My Resources Plugin Practice Project</name>
...
<build>
...
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
...
</resources>
...
</build>
...
</project>
Upon calling
mvn resources:resources
This will create a resource output in target/classes/hello.txt which contains exactly the same text.
Hello ${name}
However, if we add a <filtering> tag to our POM and set it to true like this:
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
Our target/classes/hello.txt after calling
mvn resources:resources
would be
Hello My Resources Plugin Practice Project
That's because the name variable was replaced by the value of the project's name (which was specified in the POM).
Moreover, we can also assign values through the command line using the "-D" option.
For example, to change the value for the variable name to "world", we can simply invoke this command:
mvn resources:resources -Dname="world"
And the output in target/classes/hello.txt would be
Hello world
Furthermore, we are not limited to use pre-defined project variables. We can specify our own variables and their values in the <properties> element. For example, if we want to change the variable from "name" to "your.name", we can do so by adding a <your.name> element within the <properties> element.
<project>
...
<properties>
<your.name>world</your.name>
</properties>
...
</project>
But to organize your project, you may want to put all your variables and their values in a separate file so that you will not have to rewrite your POM, or set their values all the time with every build. This can be done by adding a filter.
<project>
...
<name>My Resources Plugin Practice Project</name>
...
<build>
...
<filters>
<filter>[a filter property]</filter>
</filters>
...
</build>
...
</project>
For example, we can separate "your.name" from the POM by specifying a filter file my-filter-values.properties containing:
your.name = world
and adding that to our POM
<filters>
<filter>my-filter-values.properties</filter>
</filters>
Warning: Do not filter files with binary content like images! This will most likely result in corrupt output. If you have both text files and binary files as resources, you need to declare two mutually exclusive resource sets. The first resource set defines the files to be filtered and the other resource set defines the files to copy unaltered as illustrated below:
<project>
...
<build>
...
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/*.xml</exclude>
</excludes>
</resource>
...
</resources>
...
</build>
...
</project>
- Including and excluding files and directories
When specifying a resource directory, every file within that directory may not be used. Thus, we may have to specify only the files that we want to include or specify the files that we want to exclude.
To include a resource, we only need to add an <includes> element.
<project>
...
<name>My Resources Plugin Practice Project</name>
...
<build>
...
<resources>
<resource>
<directory>[your directory]</directory>
<includes>
<include>[resource file #1]</include>
<include>[resource file #2]</include>
<include>[resource file #3]</include>
...
<include>[resource file #n]</include>
</includes>
</resource>
...
</resources>
...
</build>
...
</project>
And to exclude a resource, we only need to add an <excludes> element.
<project>
...
<name>My Resources Plugin Practice Project</name>
...
<build>
...
<resources>
<resource>
<directory>[your directory]</directory>
<excludes>
<exclude>[non-resource file #1]</exclude>
<exclude>[non-resource file #2]</exclude>
<exclude>[non-resource file #3]</exclude>
...
<exclude>[non-resource file #n]</exclude>
</excludes>
</resource>
...
</resources>
...
</build>
...
</project>
For example, if we want to include all text and RTF files under our src/my-resources directory and in all its subdirectories, we can do the following:
<project>
...
<name>My Resources Plugin Practice Project</name>
...
<build>
...
<resources>
<resource>
<directory>src/my-resources</directory>
<includes>
<include>**/*.txt</include>
<include>**/*.rtf</include>
</includes>
</resource>
...
</resources>
...
</build>
...
</project>
Also, if we want to include everything except the bitmaps, jpegs, and gifs, we can simply exclude them by:
<project>
...
<name>My Resources Plugin Practice Project</name>
...
<build>
...
<resources>
<resource>
<directory>src/my-resources</directory>
<excludes>
<exclude>**/*.bmp</exclude>
<exclude>**/*.jpg</exclude>
<exclude>**/*.jpeg</exclude>
<exclude>**/*.gif</exclude>
</excludes>
</resource>
...
</resources>
...
</build>
...
</project>
Of course, we can also have both <includes> and <excludes> elements. For example, if we want to include all text files that does not contain the word "test" in their filename.
<project>
...
<name>My Resources Plugin Practice Project</name>
...
<build>
...
<resources>
<resource>
<directory>src/my-resources</directory>
<includes>
<include>**/*.txt</include>
</includes>
<excludes>
<exclude>**/*test*.*</exclude>
</excludes>
</resource>
...
</resources>
...
</build>
...
</project>
Escape filtering
You can escape filtering with configurable String.
This means expression ${ } and @ @ preceded will replace by the expression : \${java.home} -> ${java.home}.
The escapeString will be removed
<project> ... <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>2.6</version> <configuration> ... <escapeString>\</escapeString> ... </configuration> </plugin> </plugins> ... </build> ... </project>
Copy Resources
You can use the mojo copy-resources to copy resources which are not in the default maven layout or not declared in the build/resources element and attach it to a phase
<project>
...
<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-resources</id>
<!-- here the phase you need -->
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/extra-resources</outputDirectory>
<resources>
<resource>
<directory>src/non-packaged-resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
...
</build>
...
</project>
Binaries filtering
Now the plugin will prevent binaries files filtering without adding some excludes configuration.
By default, files with extensions (jpg, jpeg, gif, bmp and png) won't be filtered anymore.
Users can add some extra file extensions to not apply filtering with the following configuration :
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<configuration>
...
<nonFilteredFileExtensions>
<nonFilteredFileExtension>pdf</nonFilteredFileExtension>
<nonFilteredFileExtension>swf</nonFilteredFileExtension>
</nonFilteredFileExtensions>
...
</configuration>
</plugin>
</plugins>
...
</build>
...
</project>
Custom resource filters
With version 2.5 you are now able to build your own custom resources filter(s).
Your custom resources filter classes must implements org.apache.maven.shared.filtering.MavenResourcesFiltering.
Custom Resource Filter Implementation
Your custom resources filter classes must be marked as a Plexus Component. Below a sample with a roleHint itFilter.
/**
* @plexus.component role="org.apache.maven.shared.filtering.MavenResourcesFiltering"
* role-hint="itFilter"
*/
public class ItFilter
implements MavenResourcesFiltering
Then you must activate in your build the mojo which will scan javadoc annotations to transform thoses to plexus component metadata.
<plugin>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-maven-plugin</artifactId>
<version>1.3.4</version>
<executions>
<execution>
<goals>
<goal>descriptor</goal>
</goals>
</execution>
</executions>
</plugin>
Dependency declaration
Your classes must be available in the maven-resources-plugin classpath, this can be done with adding your artifact to the plugin dependencies.
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<configuration>
...
<dependencies>
<dependency>
<groupId>custom resources filters artifact groupId</groupId>
<artifactId>custom resources filters artifact artifactId</artifactId>
<version>custom resources filters artifact version</version>
</dependency>
</dependencies>
...
</configuration>
</plugin>
</plugins>
...
</build>
...
</project>
Use of your Custom Resource Filter with the maven-resources-plugin
You must now declare you custom filter in the plugin. mavenFilteringHint must respect same syntax as your Plexus Component roleHint.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>@pom.version@</version>
<configuration>
...
<mavenFilteringHints>
<mavenFilteringHint>itFilter</mavenFilteringHint>
</mavenFilteringHints>
</configuration>
...
</configuration>
</plugin>