0

Is there any way to add some information to jar during compilation. And see that information during execution to know which jar is executing.

My scenario is that I am building a jar with fixed jar name and sending it to run on another machine. However it sometimes happen that it seem to run the old version of jar. Is there any way to identify it without needing to change jar file name and providing information during compilation. I cannot change java code everytime but can do one time change if required.

Shashwat Kumar
  • 5,159
  • 2
  • 30
  • 66
  • 2
    You can put version inside the `MANIFEST.MF` and print it when you start the jar. – BackSlash Feb 27 '19 at 07:42
  • or you can add a class through which you can retrieve information (like the version) from the pom – Stultuske Feb 27 '19 at 07:43
  • And `jar` adds the java version to the manifest by default – ernest_k Feb 27 '19 at 07:43
  • I am building jar using gradle jar command. I can't make change to file multiple times. – Shashwat Kumar Feb 27 '19 at 07:43
  • Can I print manifest version using Java? I want to verify it using logs and not needing to extract jar and look into Manifest file. – Shashwat Kumar Feb 27 '19 at 07:44
  • @ShashwatKumar There's no need to modify the manifest multiple times. Just [let gradle do it for you](http://andresalmiray.com/customize-jar-manifest-entries-with-maven-gradle/). – BackSlash Feb 27 '19 at 07:45
  • you can modify your code once and check at start when app in running using `System.getProperty("java.version")` this will give you the version of java of client machine, then you can achieve what you want by using if-else – Mustahsan Feb 27 '19 at 07:47
  • @BackSlash can manifest attributes information be seen using command line directly without needing to extract jar. – Shashwat Kumar Feb 27 '19 at 07:49
  • @Mustahsan why would they want the version of java on the machine? that is not what we're talking about – Stultuske Feb 27 '19 at 07:49
  • @ShashwatKumar `unzip -q -c META-INF/MANIFEST.MF` - this will print contents directly to STDOUT (yes, it does unzip, but it's required if you want to access that file) – BackSlash Feb 27 '19 at 08:00
  • add a properties file to the jar (if not already using one) and add a key/value for the version. This file can be read using the class loader (`getClass().getResourceAsStream()` used to load `Properties`) or just use a `ReourceBundle` – user85421 Feb 27 '19 at 08:13
  • @CarlosHeuberger but then i'll need to change value in config file everytime. – Shashwat Kumar Feb 27 '19 at 08:27

1 Answers1

3

To get the version from the jar, use:

OneOfYourClasses.class.getPackage().getImplementationVersion();

This assumes that you have set the implementation version in MANIFEST.MF, which you can do at build time. It could include a date.

With Maven the maven-shade-plugin can do this for you with the ManifestResourceTransformer transformer (I'm just using the version from the pom here):

<manifestEntries>
      <Implementation-Title>${project.artifactId}</Implementation-Title>
      <Implementation-Version>${project.version}</Implementation-Version>
</manifestEntries>

There should be a similar plugin for gradle.

EDIT: Gradle does it even easier (from https://docs.gradle.org/current/userguide/java_plugin.html):

jar {
    manifest {
        attributes("Implementation-Title": "YourJarName",
                   "Implementation-Version": version)
    }
}

EDIT: if you are on Linux you can see the version from the command line with:

unzip -p yourfile.jar META-INF/MANIFEST.MF | grep Implementation-Version
ewramner
  • 5,810
  • 2
  • 17
  • 33
  • How to put version dynamically without needing to change manually? – Shashwat Kumar Feb 27 '19 at 08:14
  • The code above will use the version you have in your pom or gradle file. To make it more dynamic, add a date. See https://stackoverflow.com/questions/19172565/how-append-date-build-to-versionnamesuffix-on-gradle for examples. – ewramner Feb 27 '19 at 08:32