Get Maven artifact version at runtime
I have noticed that in a Maven artifact's JAR, the project.version attribute is included in two files:
META-INF/maven/${groupId}/${artifactId}/pom.properties
META-INF/maven/${groupId}/${artifactId}/pom.xml
Is there a recommended way to read this version at runtime?
Solution 1:
You should not need to access Maven-specific files to get the version information of any given library/class.
You can simply use getClass().getPackage().getImplementationVersion()
to get the version information that is stored in a .jar-files MANIFEST.MF
. Luckily Maven is smart enough Unfortunately Maven does not write the correct information to the manifest as well by default!
Instead one has to modify the <archive>
configuration element of the maven-jar-plugin
to set addDefaultImplementationEntries
and addDefaultSpecificationEntries
to true
, like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
</archive>
</configuration>
</plugin>
Ideally this configuration should be put into the company pom
or another base-pom.
Detailed documentation of the <archive>
element can be found in the Maven Archive documentation.
Solution 2:
To follow up the answer above, for a .war
artifact, I found I had to apply the equivalent configuration to maven-war-plugin
, rather than maven-jar-plugin
:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.1</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
</archive>
</configuration>
</plugin>
This added the version information to MANIFEST.MF
in the project's .jar
(included in WEB-INF/lib
of the .war
)
Solution 3:
Here's a method for getting the version from the pom.properties, falling back to getting it from the manifest
public synchronized String getVersion() {
String version = null;
// try to load from maven properties first
try {
Properties p = new Properties();
InputStream is = getClass().getResourceAsStream("/META-INF/maven/com.my.group/my-artefact/pom.properties");
if (is != null) {
p.load(is);
version = p.getProperty("version", "");
}
} catch (Exception e) {
// ignore
}
// fallback to using Java API
if (version == null) {
Package aPackage = getClass().getPackage();
if (aPackage != null) {
version = aPackage.getImplementationVersion();
if (version == null) {
version = aPackage.getSpecificationVersion();
}
}
}
if (version == null) {
// we could not compute the version so use a blank
version = "";
}
return version;
}