Keywords: Java | Maven | Version Management | Resource Filtering | POM Parsing
Abstract: This article comprehensively explores multiple implementation approaches for retrieving version numbers from Maven POM files in Java applications. It focuses on the static method based on resource filtering, which involves creating property files and enabling Maven resource filtering to inject project version during build time. Alternative solutions including dynamic POM file parsing and zero-configuration methods utilizing Maven-generated metadata are also analyzed. The article provides detailed comparisons covering implementation principles, configuration steps, code examples, and applicable scenarios, offering technical references for developers to choose appropriate solutions.
Introduction
In Java project development, there is often a need to retrieve current application version information at runtime for purposes such as logging, monitoring statistics, or feature toggles. As the mainstream project management tool, Maven's POM (Project Object Model) file contains complete project metadata, with version number being one of the most frequently used pieces of information. This article systematically introduces several technical solutions for retrieving version numbers from POM files.
Static Injection Method Based on Resource Filtering
This is the most stable and reliable implementation approach, involving static injection of version information into configuration files during the build phase, with direct reading at runtime. The specific implementation consists of four steps:
First, create a property file in the project's src/main/resources directory, for example version.properties. Use Maven standard properties to reference the project version in this file:
application.version=${project.version}Second, read the property file through the class loader in Java code:
Properties props = new Properties();
try (InputStream input = getClass().getClassLoader().getResourceAsStream("version.properties")) {
props.load(input);
String version = props.getProperty("application.version");
System.out.println("Application version: " + version);
} catch (IOException ex) {
ex.printStackTrace();
}Third, enable resource filtering in the POM file, which is a crucial configuration step:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>When Maven build is executed, the resource filtering mechanism automatically replaces ${project.version} with the actual version value, generating the final configuration file.
Alternative Approach: Dynamic POM File Parsing
For scenarios requiring dynamic reading of POM files, the Maven model library can be used to directly parse XML files. First, add the dependency:
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-model</artifactId>
<version>3.3.9</version>
</dependency>Then read the POM file through MavenXpp3Reader:
MavenXpp3Reader reader = new MavenXpp3Reader();
Model model = reader.read(new FileReader("pom.xml"));
String version = model.getVersion();
System.out.println("Version: " + version);This method requires consideration of file path issues, as the POM file might not be in the default location in packaged applications. An improved approach can check file existence:
if (new File("pom.xml").exists()) {
model = reader.read(new FileReader("pom.xml"));
} else {
model = reader.read(new InputStreamReader(
getClass().getResourceAsStream(
"/META-INF/maven/groupId/artifactId/pom.xml"
)
));
}Zero-Configuration Method Using Maven-Generated Metadata
Maven automatically generates META-INF/maven/${groupId}/${artifactId}/pom.properties file during packaging, containing basic project information:
#Generated by Maven
#Sun Feb 21 23:38:24 GMT 2010
version=2.5
groupId=commons-lang
artifactId=commons-langThe version information can be directly retrieved by reading this file at runtime without any additional configuration. However, note that this file is only generated during the package phase and might be unavailable in earlier phases like testing.
Solution Comparison and Selection Recommendations
Each of the three solutions has its advantages and disadvantages: the resource filtering method is most stable and suitable for production environments; dynamic parsing offers high flexibility but depends on file paths; the metadata method requires zero configuration but availability is limited by build phases. Developers should choose appropriate solutions based on specific requirements.
Extended Applications
Beyond version numbers, these methods can also retrieve other project information such as project name and description. Combined with Maven profiles and property mechanisms, more complex build-time configuration injection can be achieved to meet deployment requirements across different environments.