12.8.2009 Maven: Versionsnummer aus pom.xml und Build-Zeitstempel mit Java auslesen

Bei Verwendung von Maven ist die Ziel-Versionsnummer des eigenen Programms in der pom.xml festgelegt. Selbstverständlich kann man auch aus dem Programm heraus mit Java darauf zugreifen, denn Maven erzeugt eine pom.properties Datei unterhalb von META-INF, in der u.a. die Versionsnummer und der Zeitstempel des Build steht:

#Generated by Maven
#Fri Jul 31 15:49:26 CEST 2009
version=0.1.14
groupId=de.hoennig.samples
artifactId=maven-props

Mit dem folgenden Programmcode können diese Informationen ausgelesen werden:

package ...;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;

/** Access to the Maven pom.properties file.
 * 
 * 

The complete path where Maven puts its properties: * /META-INF/maven/GRPUP_ID/ARTIFACT_ID/pom.properties

*/ public class MavenProperties { private static final String PATH_PREFIX = "/META-INF/maven/"; private static final String PATH_POSTFIX = "/pom.properties"; final String propertiesPath; private String versionTimestamp = ""; private String versionNumber = ""; /** Uses the resource path from classForResource to load the pom.properties of the given groupID and artifactID. */ public MavenProperties(final String groupID, final String artifactID ) { propertiesPath = PATH_PREFIX + groupID + "/" + artifactID + PATH_POSTFIX; try { final InputStream resourceStream = getResourceAsStream(propertiesPath); LineNumberReader reader = new LineNumberReader( new InputStreamReader(resourceStream)); // skip "#Generated by Maven" reader.readLine(); // read "#timestamp" versionTimestamp = reader.readLine().substring(1); // find "version=..." String line; while ( null != ( line = reader.readLine() ) ) { String[] parts = line.split("[ \t]*=[ \t]*"); if ( "version".equals(parts[0]) ) { versionNumber = parts[1]; break; } } reader.close(); } catch (Exception e) { // can't load pom.properites => version information will be unavailable } } /// allows for overriding the resource loading, e.g. in tests protected InputStream getResourceAsStream(String propertiesPath) { return getClass().getResourceAsStream(propertiesPath); } /** Returns the timestamp from the Maven generated pom.properies or "" if not available. **/ public String getVersionTimestamp() { return versionTimestamp; } /** Returns the version number from the Maven generated pom.properies or "" if not available. **/ public String getVersionNumber() { return versionNumber; } }

Anzumerken sei, dass der Zeitstempel unstrukturiert als Kommentar gespeichert ist und nicht zu 100% erkannt werden kann. Falls das von Maven generierte Format geändert wird, wird dieser Zugriff leider nicht mehr funktionieren. Wer den Zeitstempel gar nicht braucht, kann natürlich den Stream auch mit einer java.util.Properties-Instanz einlesen.

Die Methode, welche die Resource lädt, kann überladen werden, was evtl. nötig ist, wenn die Klasse MavenProperties von einem fremden Classloader geladen wurde – auch für einen Unit-Test hatte ich dies benötigt, da sich java.lang.Class nur mit recht „üblen“ Tricks mocken lässt.