Explain Codes LogoExplain Codes Logo

Retrieve version from maven pom.xml in code

java
maven
pom-xml
version-retrieval
Alex KataevbyAlex Kataev·Nov 9, 2024
TLDR

Use Maven resource filtering for injecting the Maven project's version at runtime in your code.

  1. Apply filtering to pom.xml:
<build> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> </build>
  1. Create version.properties in src/main/resources:
version=${project.version}

Maven swaps ${project.version} for the current version during the build.

  1. Load the property in Java:
Properties props = new Properties(); props.load(getClass().getResourceAsStream("/version.properties")); String version = props.getProperty("version"); // Side-note: No, `version` is not a Doctor Who reference, it's your Maven project's version.

Voila! You have the Maven project's version in your Java code.

A pinch of Maven profiles to spice things up

Boost the Maven build's flexibility with Maven profiles. Tailor your properties file to the active profile by defining different version identifiers or other environment-specific parameters.

<profiles> <profile> <id>dev</id> <properties> <env.version>1.0.0-SNAPSHOT</env.version> // Note: `-SNAPSHOT` might not be a picture! It's a pre-release in Maven. </properties> </profile> <profile> <id>release</id> <properties> <env.version>${project.version}</env.version> // Note: When you see `${project.version}`, it's not a math equation. It's Maven magic! </properties> </profile> </profiles>

Remember to set your resource filtering to ${env.version} to make this magic work.

Ensuring version retrieval during tests

Running unit tests might prompt the infamous "properties file missing." To tackle this, ensure your test setup mirrors the primary build's resource handling in your pom.xml.

<testResources> <testResource> <directory>src/test/resources</directory> <filtering>true</filtering> // Any version missing here? No! Because resource filtering is doing its job. </testResource> </testResources>

Consider tweaking the maven-jar-plugin to embed version info for MANIFEST.MF.

<plugin> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <addDefaultImplementationEntries>true</addDefaultImplementationEntries> </manifest> </archive> </configuration> </plugin>

This way, if the properties method fails, App.class.getPackage().getImplementationVersion() comes to rescue, like your favorite superhero.

The art of reading pom.xml programmatically

Project situations may not always favor reading from the properties file. You can navigate your pom.xml programmatically using Apache Maven libraries_.

MavenXpp3Reader reader = new MavenXpp3Reader(); Model model; if ((new File("pom.xml")).exists()) model = reader.read(new FileReader("pom.xml")); else model = reader.read( new InputStreamReader( App.class.getResourceAsStream("/META-INF/maven/project.groupId/project.artifactId/pom.xml") ) ); String version = model.getVersion(); // No, we're not versioning strings here! We're getting the version from `pom.xml`.

Remember to include maven-model in your project dependency before "pom-ing" around.

From carve-stone to Swiss Army Knife approach with Maven

Though Maven primarily aids the build process, it could turn into a Swiss-Army knife, making runtime behaviors more adjustable. For instance, besides version info, pom.properties could also be honed for groupId and artifactId.

String groupId = prop.getProperty("groupId"); String version = prop.getProperty("version"); String artifactId = prop.getProperty("artifactId"); // All together, it feels like the ultimate package. Too much power!

During the Maven package phase, these values generate automatically, proving to be handy at runtime.

Effective Version Retrieval: Building the Perfect Execution

The getImplementationVersion() method is efficient for getting your project's version, but incorporating best practices adds robustness and reliability.

  • Make the best use of maven-jar-plugin and fine-tune your JAR's MANIFEST.MF to snapshot version info.
  • Robust testing ensures the version retrieval works in all environments, strengthening the integration with CI/CD pipelines.
  • Respect Maven's non-goal philosophy: Using Maven for reading pom.xml during runtime is not recommended. Indirect data access via properties and manifest files is preferred.

When you consider all these, you're preparing a recipe not just for version retrieval but for a resilient and adaptable system with clear benefits.