3

For supporting purposes I need to add a version and build identifier to our Java library. The library itself is a toolkit without user interaction which is used in different environments (stand alone Java applications, web applications, Eclipse applications, Maven dependency, ...).

What I want, is a class with some constants giving me the above described information (such as MyAppVersion.BUILD, ...), so that they can be shown e.g. in dialogs, command line output, etc. After my research, there seem to be the following approaches:

  • add versioning to file name, such as myLibrary-0.1.2.jar; not feasible in our case, since I have no control over the file name when deployed
  • add information to the MANIFEST.MF and read it programmatically, like described here. I'm not sure however, how robust this approach is in respect to different class loaders (Eclipse, OSGi, application servers, ...) and if the JAR file gets re-packaged, this information is lost
  • use a version.properties file holding the version, as described here and use a script during build to update the version.properties file
  • hard code the version information into the class directly and use a script to update this information

Are there any other approaches? The last option seems most "robust" to me, are there any objections against this variant? Is there a Maven plugin which would support updating this information in a MyAppVersion.java file during build?

Community
  • 1
  • 1
qqilihq
  • 10,794
  • 7
  • 48
  • 89
  • [This answer](http://stackoverflow.com/a/5204380/418556) provides a cleaner way to get the version from the manifest. In a nutshell: `String version = this.getClass().getPackage().getImplementationVersion();` – Andrew Thompson Jan 01 '14 at 15:20
  • Sounds Like http://stackoverflow.com/questions/2712970/how-to-get-maven-artifact-version-at-runtime – Rakesh KR Jan 01 '14 at 15:21
  • Use a properties file and filter it with maven asking it to insert the version numbers. – Boris the Spider Jan 01 '14 at 15:23

2 Answers2

3

I would suggest to use the templating-maven-plugin which is created exactly for such purposes.

You create at best a separate module which contains a template class like this (or within your module):

public final class Version {

    private static final String VERSION = "${project.version}";
    private static final String GROUPID = "${project.groupId}";
    private static final String SVN = "${project.scm.developerConnection}";
    private static final String SVN_BRANCH = "${scmBranch}";
    private static final String REVISION = "${buildNumber}";

    public static String getVersion() {
        return VERSION;
    }

    public static String getGroupId() {
        return GROUPID;
    }

    public static String getSVN() {
        return SVN;
    }

    public static String getRevision() {
        return REVISION;
    }

    public static String getSVNBranch() {
        return SVN_BRANCH;
    }
}

Which you simply put into src/main/java-templates folder plus an appropriate package name. Furthermore you configure the templating-maven-plugin like the following in your pom file:

   <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>templating-maven-plugin</artifactId>
        <version>1.0-alpha-3</version>
        <executions>
          <execution>
            <goals>
              <goal>filter-sources</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

This will generate a class Version which can be used by others and contains the given version. In the above template class you can use any property which is available in your build (things like JENKINS_ID etc.) or things your might define by yourself.

The result is that this class is compiled and packaged into your jar file.

Apart from that you can combine that with the buildnumber-maven-plugin to create the buildNumber which needs to be added to your pom file like this:

  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>buildnumber-maven-plugin</artifactId>
    <version>1.2</version>
    <configuration>
      <revisionOnScmFailure>UNKNOWN</revisionOnScmFailure>
      <getRevisionOnlyOnce>true</getRevisionOnlyOnce>
    </configuration>
    <executions>
      <execution>
        <goals>
          <goal>create</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
khmarbaise
  • 92,914
  • 28
  • 189
  • 235
0

The last option of hardcoding the version is the most robust which seems to be important to you. If you build using ant, you can write a class (let's call it VersionGenerator) that will generate a java file with version:

package my.cool.package;
public interface Version {
    String VERSION = "1.2.3";
}

Call VersionGenerator from ant And then compile all your code and roll it into a jar. And your jar will contain a freshly generated and compiled Version.class! VersionGenerator will have the logic of how to name and increase versions

Daniel Nuriyev
  • 635
  • 6
  • 10