Create Version.java file in Maven

I have a Java project that I create using an Ant script. I am trying to convert a project to Maven.

One of the tasks creates a Java source file called Version.java, which contains a static representation of the compilation timestamp:

package com.foo.bar; public final class Version { public static String VERSION="100301.1046"; } 

The Ant task is very simple:

 <target name="version" depends="init" description="Create Version.java"> <echo file="src/${package.dir}/Version.java" message="package ${package.name};${line.separator}" /> <echo file="src/${package.dir}/Version.java" append="true" message="public final class Version {${line.separator}" /> <echo file="src/${package.dir}/Version.java" append="true" message=" public static String VERSION=&quot;${buildtime}&quot;;${line.separator}" /> <echo file="src/${package.dir}/Version.java" append="true" message="}${line.separator}" /> <echo message="BUILD ${buildtime}" /> </target> 

Is it possible to do something similar in Maven using generation sources or some other simple method?

+47
java maven-2 code-generation
Mar 18
source share
10 answers

After more googling, I came up with this (in pom.xml):

 <plugins> ... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.3</version> <executions> <execution> <goals> <goal>run</goal> </goals> <phase>generate-sources</phase> <configuration> <tasks> <property name="src.dir" value="${project.build.sourceDirectory}" /> <property name="package.dir" value="com/foo/bar" /> <property name="package.name" value="com.foo.bar" /> <property name="buildtime" value="${maven.build.timestamp}" /> <echo file="${src.dir}/${package.dir}/Version.java" message="package ${package.name};${line.separator}" /> <echo file="${src.dir}/${package.dir}/Version.java" append="true" message="public final class Version {${line.separator}" /> <echo file="${src.dir}/${package.dir}/Version.java" append="true" message=" public static String VERSION=&quot;${buildtime}&quot;;${line.separator}" /> <echo file="${src.dir}/${package.dir}/Version.java" append="true" message="}${line.separator}" /> <echo message="BUILD ${buildtime}" /> </tasks> </configuration> </execution> </executions> </plugin> ... </plugins> 

It seems to work fine and create this Java file:

 package com.foo.bar; public final class Version { public static String VERSION="100318.1211"; } 
+6
Mar 18 '10 at 16:17
source share

I do not think this is a good way to solve this problem.

It’s best to place version information in the properties file that your Java program will read:

Your properties file will contain the following line:

 myapp.version=${project.version} 

Then in your pom.xml specify that the file will be filtered by Maven:

 <resources> <resource> <directory>the/directory/that/contains/your/properties/file</directory> <filtering>true</filtering> </resource> </resources> 

When Maven creates your application, it will replace all ${...} with their value. By default, ${project.version} defines the version of pom.xml (that is, the value of the <version> ).

Then in your Java code, you just need to load the properties file and get the value of the myApp.version property.

Note that you can use the Build Number plugin to install something more “complex” than just your current version (for example, if you want to put the build time in your property).

+73
Mar 18 '10 at 13:24
source share

You can also use maven-replacer-plugin if you feel that ant is a little ugly: Maybe pom enrty:

 <project> ... <properties> <version.template.file>src/main/java/com/stackoverflowVersion.java.template</version.template.file> <version.file>src/main/java/com/stackoverflow/Version.java</version.file> </properties> ... <build> <plugins> <plugin> <groupId>com.google.code.maven-replacer-plugin</groupId> <artifactId>maven-replacer-plugin</artifactId> <version>1.4.0</version> <executions> <execution> <phase>process-sources</phase> <goals> <goal>replace</goal> </goals> </execution> </executions> <configuration> <file>${version.template.file}</file> <outputFile>${version.file}</outputFile> <replacements> <replacement> <token>@buildnumber@</token> <value>${svn.revision}</value> </replacement> <replacement> <token>@buildtime@</token> <value>${maven.build.timestamp}</value> </replacement> <replacement> <token>@pomversion@</token> <value>${project.version}</value> </replacement> </replacements> </configuration> </plugin> </plugins> </build> ... </project> 

The Version.java.template file can be:

 package com.stackoverflow; public final class Version { public static final String build_number="@buildnumber@"; public static final String build_time="@buildtime@"; public static final String pomversion="@pomversion@"; } 
+24
Jan 11 '12 at 10:12
source share

Here is another solution that will give the same thing as Ralph, using pom properties filtering and a template file:

Template file (VersionJava.template placed in src / main / resources / version):

 package ${ver.package.name}; public final class ${ver.class.name} { public static String VERSION="${ver.buildtime}"; } 

POM:

 <properties> ... <ver.package.dir>com/foo/bar${project.artifactId}</ver.package.dir> <ver.package.name>com.foo.bar${project.artifactId}</ver.package.name> <ver.class.name>Version</ver.class.name> <ver.buildtime>${maven.build.timestamp}</ver.buildtime> <ver.template.dir>src/main/resources/version</ver.template.dir> <ver.template.file>VersionJava.template</ver.template.file> </properties> <build> <resources> <resource> <directory>src/main/resources</directory> <excludes> <exclude>version/*</exclude> </excludes> </resource> <resource> <directory>${ver.template.dir}</directory> <includes> <include>*.java</include> </includes> <filtering>true</filtering> <targetPath>${basedir}/src/main/java/${ver.package.dir}</targetPath> </resource> </resources> <plugins> <plugin> <artifactId>maven-antrun-plugin</artifactId> <executions> <execution> <phase>generate-sources</phase> <configuration> <tasks> <copy file="${ver.template.dir}/${ver.template.file}" tofile="${ver.template.dir}/${ver.class.name}.java" /> </tasks> </configuration> <goals> <goal>run</goal> </goals> </execution> <execution> <phase>compile</phase> <configuration> <tasks> <delete file="${ver.template.dir}/${ver.class.name}.java" /> </tasks> </configuration> <goals> <goal>run</goal> </goals> </execution> </executions> </plugin> </plugins> </build> 

Now this may seem excessive, but it is extremely versatile, and what I like most is that I have a template file in a readable format (and not in the echo reports in pom). It also allows me to change the version class without changing pom

+11
Aug 23 '11 at 12:53 on
source share

This is an old question, but there is another solution that does an excellent job (in the sense of Maven) perfectly: Maven plugin template .

Using this plugin causes the processed Java file to be placed in the target/generated-sources folder, as you would expect. And he adds the folder under generated-sources to the build path. You will no longer register the processed file by mistake.

How to use

First put the following in src/main/java-templates/com/foo/bar/Version.java :

 package com.foo.bar; public final class Version { public static final String VERSION = "${project.version}"; } 

Then add the following to your POM:

 <build> <plugins> ... <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>templating-maven-plugin</artifactId> <version>1.0.0</version> <executions> <execution> <id>filtering-java-templates</id> <goals> <goal>filter-sources</goal> </goals> </execution> </executions> </plugin> ... </plugins> </build> 

The target/generated-sources/java-templates folder is added to the Maven build path.

+11
Apr 14 '16 at 16:24
source share

Based on answer from @superole . This is a simplified version without the need to set additional properties. Only the project version is copied to Version.java.

Put Version.java in src/main/templates :

 package thepackage; public final class Version { public static String VERSION="${project.version}"; } 

Ask maven to replace tokens in Version.java

 <resources> <resource> <directory>src/main/templates</directory> <includes> <include>*.java</include> </includes> <filtering>true</filtering> <targetPath>${project.build.directory}/generated-sources/java/thepackage</targetPath> </resource> </resources> 

Ask maven to recognize generated-sources/java as a build path:

 <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>1.8</version> <executions> <execution> <id>add-source</id> <phase>generate-sources</phase> <goals> <goal>add-source</goal> </goals> <configuration> <sources> <source>${project.build.directory}/generated-sources/java/</source> </sources> </configuration> </execution> </executions> </plugin> 

Finally, let Eclipse m2e

  • know a new build path
  • and not get into an infinite loop assembly.

The second point is achieved by disabling using the maven-resources-plugin during the incremental build of eclipse.

 <pluginManagement> <plugins> <plugin> <groupId>org.eclipse.m2e</groupId> <artifactId>lifecycle-mapping</artifactId> <version>1.0.0</version> <configuration> <lifecycleMappingMetadata> <pluginExecutions> <pluginExecution> <pluginExecutionFilter> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <versionRange>[1.0,)</versionRange> <goals> <goal>parse-version</goal> <goal>add-source</goal> <goal>maven-version</goal> <goal>add-resource</goal> <goal>add-test-resource</goal> <goal>add-test-source</goal> </goals> </pluginExecutionFilter> <action> <execute> <runOnConfiguration>true</runOnConfiguration> <runOnIncremental>true</runOnIncremental> </execute> </action> </pluginExecution> <pluginExecution> <pluginExecutionFilter> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <versionRange>[1.0.0,)</versionRange> <goals> <goal>resources</goal> </goals> </pluginExecutionFilter> <action> <execute> <runOnConfiguration>true</runOnConfiguration> <runOnIncremental>false</runOnIncremental> </execute> </action> </pluginExecution> </pluginExecutions> </lifecycleMappingMetadata> </configuration> </plugin> </plugins> </pluginManagement> 

thepackage should be replaced with your package: also adjust targetPath . It was easier for me to set the path in targetPath instead of having many subfolders in src/main/templates .

+7
Nov 27 '13 at 18:09
source share

As suggested by @Romain, you can read the version from the properties file (or /META-INF/maven/groupId/artifactId/pom.properties if you can wait until you pack or flip your own filtered file if you cannot or if it does not provide everything that you need).

And you want to stick with your actual Version class, and then look at this thread in the maven user list, which definitely offers a solution for this (based on the antrun plugin that you will link in the generated-sources phase).

+3
Mar 18
source share
+2
Apr 29 2018-11-21T00:
source share

The standard way to do this with very few lines of XML code now is to use the templating-maven plugin.

See my answer in Source Filtering in Maven

In general, the Maven way is to describe what you want to do. Then depict how . When you need dozens or hundreds of XML lines, either find the right plugin that does this, or write. This was the rationale that the templating-maven plugin created :-).

+1
Aug 26 '13 at 21:48
source share

I do this using the Maven WAR Plugin , adding information to MANIFEST.MF , and then reading this MANIFEST.MF file in Java:

  <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.6</version> <configuration> <archive> <manifest> <addDefaultImplementationEntries>true</addDefaultImplementationEntries> <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries> </manifest> <manifestEntries> <Build-Time>${maven.build.timestamp}</Build-Time> </manifestEntries> </archive> </configuration> </plugin> 

This configuration generates the following MANIFEST.MF file:

 Manifest-Version: 1.0 Implementation-Title: MyApp Implementation-Version: 2.11.0-SNAPSHOT Built-By: niestroj Specification-Title: MyApp Implementation-Vendor-Id: com.mycompany Build-Time: 2017-01-09 15:30 Created-By: Apache Maven 3.0.5 Build-Jdk: 1.8.0_40 Specification-Version: 2.11 

And later I read this in Java as follows:

  try { Manifest manifest = new Manifest(getServletContext().getResourceAsStream("/META-INF/MANIFEST.MF")); Attributes attributes = manifest.getMainAttributes(); attributes.getValue("Implementation-Version"); attributes.getValue("Build-Time"); } catch (IOException ex) { LOGGER.debug("Error reading manifest file information", ex); } 
+1
Dec 30 '15 at 11:14
source share



All Articles