I use the maven-resource-plugin to filter some resources in my maven project. In my parent project I have:
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
In a sub project I have a test.properties file which is a plain java properties file with default encoding=ISO-8859-1. This file contains:
aboutText=Version ${project.version} © 2012 blabla
To make sure this file filters correctly I have split the maven-resource-plugin into separate executions each with its encoding:
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>ico</nonFilteredFileExtension>
<nonFilteredFileExtension>jar</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
<executions>
<execution>
<id>filter-properties-files</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<!-- java properties files are encoded in ISO-8859-1 so when
filtering those files we stick with that encoding. -->
<encoding>ISO-8859-1</encoding>
<outputDirectory>${basedir}/after</outputDirectory>
<resources>
<resource>
<filtering>true</filtering>
<directory>${basedir}/before</directory>
<includes>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
<execution>
<id>filter-non-properties-files</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
<outputDirectory>${basedir}/after</outputDirectory>
<resources>
<resource>
<filtering>true</filtering>
<directory>${basedir}/before</directory>
<includes>
<include>**/*.product</include>
<include>**/*.inf</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
This seems overkill and I have a feeling that I am either not using the plugin correctly or that this problem should be handled in another way. Maybe stick to encoding special characters in properties files directly:
aboutText=Version ${project.version} \u00a9 2012 blabla
?
The question is an invaluable answer in itself, as apparently the complicated procedure the author provides is the only way to configure different encodings for various filtered file types. The example given, however, is specific to the author's non-standard use-case, and glosses over a few important details, without which actual use of the example is fraught with gotchas:
resources
is still enabled and runs in addition to the two defined goals!generate-resources
instead of the default process-resources
. This is a trick to get around the first point above; by making the two copy-resources
goals occur in an earlier lifecycle phase, the resources are copied according to the given rules, and then when the default-resources
goal comes along the original resource copying is left intact, apparently because its overwrite
setting defaults false
. But it would be better to disable altogether the default-resources
execution.outputDirectory
declaration. It would be natural to think that the author only provided this because a custom output directory was desired; after all, the resources
goal provides a default value for this setting. Strangely, though, for the copy-resources
goal this setting is actually required! There is a standard Maven variable ${project.build.outputDirectory}
which can be used as the value, however.Building on the author's own example in the question, here is a cut-and-paste way to filter properties files using ISO-8859-1, copy other files without filtering, and prevent the default resource copying from occurring; all using the standard source and target directories:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<!-- Turn off default resource copying. -->
<id>default-resources</id>
<phase />
</execution>
<execution>
<!-- Filter resources in properties files. -->
<id>filter-properties-files</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<encoding>ISO-8859-1</encoding>
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
<execution>
<!-- Do not do property substitution in files that are not properties files, such as binary files. -->
<id>copy-other-resources</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/*.properties</exclude>
</excludes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
Update: After more research, I believe that instead of disabling the default execution, one could simply modify the default execution to ignore properties files, and add filtering of properties files as an additional execution. Moreover if the resources
goal were used instead of copy-resources
, there would be no need to indicate an output directory or a phase, as resources:resources
automatically binds to the process-resources
phase and outputs to ${project.build.outputDirectory}
. Note that I've updated to version 3.1.0 of the plugin, so perhaps some of these options were not available in the version I used above. I have not tested this new, shorter configuration.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<!-- Ignore properties files by default. -->
<id>default-resources</id>
<configuration>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
<excludes>
<exclude>**/*.properties</exclude>
</excludes>
</resource>
</resources>
</configuration>
</execution>
<execution>
<!-- Filter resources in properties files using ISO-8859-1. -->
<id>filter-properties-files</id>
<goals>
<goal>resources</goal>
</goals>
<configuration>
<encoding>ISO-8859-1</encoding>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
Maybe someone could test this new configuration and let me know if it works the same as the original one I gave above.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With