Maven Shade Plugin's PropertiesTransformer with examples
Maven Shade Plugin is an extension that allows you to combine dependencies during the project build process. The purpose of this plugin is to create one JAR file containing all the application dependencies and its code.
Within this process, merging configuration files, such as *.properties
, can sometimes be problematic. By default, the
last encountered file will win its place in the resulting artifact.
The plugin offers configuration using so-called transformers to resolve such problems and influence the behavior of resource merging.
Transformacja PropertiesTransformer
The plugin itself offers multiple pre-installed transformers. More complex ones you can import from external providers. Since
version 3.2.2, the developers have also provided an implementation
of org.apache.maven.plugins.shade.resource.properties.PropertiesTransformer
.
It's name can sound quite promising when you need to change the order of combining properties.
You may want this for the application to load the preferred (usually overridden) properties.
If you take a look at the PropertiesTransformer and try the example configuration (referenced below), you might have a hard time reaching your expected result. The explanation of the properties may seem a bit superficial, which is why it's best to see the behavior on the examples (version 3.4.1).
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.properties.PropertiesTransformer">
<!-- required configuration -->
<resource>configuration/application.properties</resource>
<ordinalKey>ordinal</ordinalKey>
<!-- optional configuration -->
<alreadyMergedKey>already_merged</alreadyMergedKey>
<defaultOrdinal>0</defaultOrdinal>
<reverseOrder>false</reverseOrder>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
Having two configuration/application.properties
files from module A and module B respectively:
#module-a configuration/application.properties
prop1=A
prop2=B
#module-b configuration/application.properties
prop2=C
prop3=D
the maven-shade-plugin's shade goal with the PropertiesTransformer combining both dependencies will produce the following configuration/application.properties
file by default:
# Merged by maven-shade-plugin (org.apache.maven.plugins.shade.resource.properties.PropertiesTransformer)
prop1=A
prop2=C
prop3=D
ordinalKey and defaultOrdinal
The order in which the files will be merged is controlled by the ordinalKey
pointing to the name of the property
whose value is the numeric order. If the properties file does not contain such a key, its order is defined by the defaultOrdinal
(0 if missing).
By defining a higher than the default order in module A file:
#module-a configuration/application.properties
prop1=A
prop2=B
ordinal=1
#module-b configuration/application.properties
prop2=C
prop3=D
in the output, you will get the property prop2
from module A, i.e., effectively achieving the reversed order.
Additionally, the transformer will remove the artificial key:
# Merged by maven-shade-plugin (org.apache.maven.plugins.shade.resource.properties.PropertiesTransformer)
prop1=A
prop2=B
prop3=D
alreadyMergedKey
The alreadyMergedKey
defines a boolean
value type (e.g., a true
String) property name that indicates file priority.
This way, the transformer will not merge other files into this one.
#module-a configuration/application.properties
prop1=A
prop2=B
already_merged=true
#module-b configuration/application.properties
prop2=C
prop3=D
For such properties, you'll get a copy of properties from module A, again with the already_merged
synthetic key removed:
# Merged by maven-shade-plugin (org.apache.maven.plugins.shade.resource.properties.PropertiesTransformer)
prop1=A
prop2=B
The occurrence of such a key with a true
value in more than one file is not allowed and will result in an error.
reverseOrder
You can use the reverseOrder
option to reverse the order of concatenating files. Unfortunately, this feature
does not reverse the order between files with the same order value. I.e., for <reverseOrder>true</reverseOrder>
and two
property files:
#module-a configuration/application.properties
prop1=A
prop2=B
#module-b configuration/application.properties
prop2=C
prop3=D
you will still (regardless of the value of the reverseOrder
) get the same result:
# Merged by maven-shade-plugin (org.apache.maven.plugins.shade.resource.properties.PropertiesTransformer)
prop1=A
prop2=C
prop3=D
The reversal works only after defining the order with ordinalKey
and only between the files of a different order.
Summary
The PropertiesTransformer
allows for the basic merging of property files. It is worth knowing that files are initially loaded
using java.util.Properties
. It means that duplicates are overwritten with the most recent (closest to the bottom) property within the
same file.
To determine the order of file merging or designate a priority file among multiple files, you must include an artificial key. Regrettably, reversing the order between files with identical or default order values is not feasible.
So if you need a slightly different merging behavior (e.g., without the need to add artificial keys), look for external add-on packs with custom transformers.
You can easily add such a dependency using the <dependencies></dependencies>
tag inside the <plugin></plugin>
.
If you simply want to combine the properties in reverse order, take a look at the
org.kordamp.shade:maven-shade-ext-transformers:1.4.0.