Maven 2: How to pack the current version of a project in a WAR file?

I am using Maven 2 to create my Java project, and I am looking for a way to present the current pom.xml version number to the user (e.g. using a servlet or JSP).

As far as I can tell, the best way would be for Maven to pack the version number into a text file in WAR. This allows me to read the version from this file and present it the way I want.

Does anyone know of a plugin that can do something similar for me? Maybe the WAR plugin can be configured this way? Or perhaps use some other approach?

+6
java maven-2 version
source share
5 answers

You want to do resource filtering. This is done before the military plug-in creates the file. I am pretty sure that the war-pack plugin adds a version to web.xml and the manifest, but I'm not sure how to access them through the servlet APIs, but it can also be valid.

Take a look at the Maven resource plugin documentation, it will tell you how to do it. I think you should just replace the version using ${version} . I don't have a working maven installation to check it out here.

+5
source share

I solved this problem a little differently, as I had a desire to display the version, svn revision, etc. on the service index page. I used buildnumber-maven-plugin and war-plugin to store values ​​in the manifest.

pom.xml snippet:

 <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>buildnumber-maven-plugin</artifactId> <executions> <execution> <phase>validate</phase> <goals> <goal>create</goal> </goals> </execution> </executions> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <configuration> <archive> <manifest> <addDefaultImplementationEntries>true</addDefaultImplementationEntries> </manifest> <manifestEntries> <Implementation-Environment>${env}</Implementation-Environment> <Implementation-Build>${buildNumber}</Implementation-Build> </manifestEntries> </archive> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>war</goal> </goals> <configuration> <classifier>${env}</classifier> </configuration> </execution> </executions> </plugin> 

JSP to pull them out was pretty trivial:

 <%@ page language="java" pageEncoding="UTF-8"%> <% java.util.jar.Manifest manifest = new java.util.jar.Manifest(); manifest.read(pageContext.getServletContext().getResourceAsStream("/META-INF/MANIFEST.MF")); java.util.jar.Attributes attributes = manifest.getMainAttributes(); %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Health Check</title> </head> <body> <h1>Health Check</h1> <h2>Version: <%=attributes.getValue("Implementation-Version")%>-<%=attributes.getValue("Implementation-Environment")%></h2> <h2>SVN Revision: <%=attributes.getValue("Implementation-Build")%></h2> </body> </html> 

It displayed something like this:

 Version: 2.0.1-SNAPSHOT-QA SVN Revision: 932 
+10
source share

Of course, variables can be included in resources and filtered with the maven-resource plugin by adding the <filtering> to the POM and set the value to true as follows:

 ... <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> ... 

And you can use this function to read and replace ${version} (or ${project.version} or ${pom.version} , which are equivalent) in the properties file, for example.

But in fact, the information you are looking for is provided by default to Maven (unless you have configured it so that it is unlikely if you do not know about it). If you unpack the WAR that Maven created for you and take a look at it, you will see the following:

 |-- META-INF | |-- MANIFEST.MF | `-- maven | `-- com.mycompany.app | `-- my-app | |-- pom.properties | `-- pom.xml |-- WEB-INF | |-- classes | | |-- ... | |-- lib | | |-- ... | `-- web.xml |-- bar.jsp |-- ... `-- foo.jsp 

As you can see, you will find the pom.xm and pom.properties file in it and, as described in How to add resources to my JAR? :

pom.xml and pom.properties files are packaged in a JAR, so every artifact created by Maven is self-describing, and also allows you to use metadata in your own if the need arises. One simple use may be the version of your application. operating in the POM file you will need to use some Maven utilities, but the properties can be used using the standard Java API and look like the following:

 #Generated by Maven #Tue Oct 04 15:43:21 GMT-05:00 2005 version=1.0-SNAPSHOT groupId=com.mycompany.app artifactId=my-app 

So you can just download this pom.properties file with something like this (pseudo code):

 // Retrieve resource InputStream is = getClass().getResourceAsStream( "/META-INF/maven/com.mycompany.app/my-app/pom.properties" ); // Do something with the resource, eg load it as Properties Properties prop = new Properties(); prop.load(is); String version = prop.getProperty("version"); 
+7
source share

My solution for the standard Maven WAR plugin

Add a resource tag to the assembly section, which allows you to filter (aka "search and replace"):

 <build> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> .... <build> 

Then in your src / main / resources add the version.properties file containing any filter variables that correspond to one of the standard maven assembly variables (you can also use the filter function to load your own custom variables):

 pom.version=${pom.version} 

Now when you do a “maven package” or install maven, it copies the version.properties file to the WEB-INF / classes and performs a search and replace to add the pom version to the file.

To get this using Java, use a class, for example:

 public class PomVersion { final private static Logger LOGGER = LogManager.getLogger(PomVersion.class); final static String VERSION = loadVersion(); private static String loadVersion() { Properties properties = new Properties(); try { InputStream inStream = PomVersion.class.getClassLoader().getResourceAsStream("version.properties"); properties.load(inStream); } catch (Exception e){ LOGGER.warn("Unable to load version.properties using PomVersion.class.getClassLoader().getResourceAsStream(...)", e); } return properties.getProperty("pom.version"); } public static String getVersion(){ return VERSION; } } 

Now you can simply call PomVersion.getVersion () to put the version number of the pom file on the page. You can also get the WAR file with the same number using the filter variable in finalName inside pom.xml:

 <build> <finalName>my-killer-app-${pom.version}</finalName> ... </build> 

so now if you install the version of your application in your pom as 01.02.879:

 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.killer.app</groupId> <artifactId>my-killer-app</artifactId> <packaging>war</packaging> <name>This App Will Rule The World</name> <version>01.02.879</version> ... </project> 

when you run "mvn install", the name of the war file includes the version number:

 my-killer-app-01.02.879.war 

Finally, if you use Spring heavily, for example using SpringMVC / SpringWebFlow, you can make an oneton bean service that uses this class to avoid referencing a low-level class by name:

 @Service("applicationVersion") public class ApplicationVersion { final static String VERSION = PomVersion.getVersion(); public String getVersion() { return VERSION; } } 
+7
source share

In the answers, we see several options for the “upload properties file” method, and I'm going to add another alternative version to it that works with Maven 3.5 , but probably also with older versions.


Step 0: pom.xml

You just need to do something in pom.xml ; include something called resource filtering. This is easy to do if you find the <build> and put your resource folder that you want to filter there. It will look like this:

 <project ...> ... <build> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> ... </build> ... </project> 

Note: elipsis ... means code omitted

if you want, you can also add your custom variables, but this is optional :

 <project ...> <properties> <build.version>1.1-SNAPSHOT</build.version> </properties> ... </project> 


Step 1: properties file

Create a .properties file and put it in the maven resource file. I am going to name my application.properties . For simplicity, I'm going to put it in the default resources folder; src/main/resources , but you can edit this in almost any folder you want.

 |-- pom.xml |-- src |-- main |-- java |-- webapp |-- resources `-- application.properties 

In the application.properties file, I am going to add the version property that I want:

 author=eFox build=${build.version} version=${project.version} # This is the default maven variable that you could and should use. 


Step 2 Page * .JSP

Here my method is different from the above versions. Instead of loading the properties file as the Property class, load META-INF pom.properties or make it a controller class, we will load it as a resource:

 <%@ page import = "java.util.ResourceBundle" %> <% ResourceBundle resource = ResourceBundle.getBundle("application"); String version = resource.getString("version"); String author = resource.getString("author");%> <html> <head> ... </head> <body> ... Site version: <%=version %> by <%=author%> </body> </html> 
+1
source share

All Articles