7

Thanks in advance for any help.

What I want to achieve is project version (Implementation-Version) is printed in a class when it is initiated so that I can trace the version from log file.

I build a JAR file containing the following classes:

com.company.core.common.ClassA
com.company.core.security.ClassB
com.company.core.sql.ClassC

In constructor of com.company.core.sql.ClassC, I want to call System.out.println() to print out the Implementation-Version stored in META-INF/MANIFEST.MF file by calling this.class.getPackage().getImplementationVersion(), but it is getting null value when the class is initiated via Maven test class.

My MANIFEST.MF file contains the following details:

Manifest-Version: 1.0
Implementation-Title: Company Core Library
Implementation-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: simon
Implementation-Vendor-Id: com.company.core
Build-Time: 2017-02-18T15:07:33Z
Class-Path: lib/sqljdbc42-4.2.jar lib/log4j-api-2.7.jar lib/log4j-core
 -2.7.jar lib/json-20160810.jar lib/junit-4.12.jar lib/hamcrest-core-1
 .3.jar
Created-By: Apache Maven 3.3.9
Build-Jdk: 1.8.0_102
Implementation-Vendor: Company

Name: com/company/core/
Implementation-Vendor-Id: com.company.core
Implementation-Title: Company Core Library
Implementation-Version: 1.0
Implementation-Vendor: Company

Would I be able to get the Implementation-Version in Maven test class? If yes, what have I missed out here?

Thanks.

Regards, Simon.

Gerold Broser
  • 14,080
  • 5
  • 48
  • 107
Simon Tneoh
  • 71
  • 1
  • 1
  • 2
  • How are you creating your manifest? Can you please show your pom file? – khmarbaise Feb 18 '17 at 18:13
  • `com.company.core.sql.ClassC` is not in the package defined in your `MANIFEST.MF` (`Name: com/company/core/`), but in one of its sub-packages. What if you change `Name: com/company/core/` to `Name: com/company/core/sql/`? – Gerold Broser Feb 18 '17 at 19:00
  • Hi Gerold, in Scott's reply at the end in [link](http://stackoverflow.com/questions/33553570/how-to-read-meta-data-from-manifest-file/38645453#38645453) thread, sub level shall work. Anyway, I tried that but getting null value as well. – Simon Tneoh Feb 19 '17 at 09:31
  • Hi khmarbaise, the POM file is quite big, any specific segment that you would like to take a look? I wonder besides MANIFEST.MF file, any other important details are needed when Package.getImplementationVersion() is called? – Simon Tneoh Feb 19 '17 at 09:36
  • I have the same issue, see [link](https://stackoverflow.com/questions/38204059/how-to-obtain-a-package-version-from-the-jars-manifest-using-the-getimplementa). The question was posted in July 2016 and I still don't know why it does not work. In my code, I used a workaround. – m. vokhm Nov 25 '17 at 09:38
  • I also got null for 'Implementation-Version' when I run test task of gradle. In my case I found that the class using to get 'Implementation-Version' was loaded from build dir while not from the jar file which has a MANIFEST.MF file in it. I do a workaround with help of following answer: [link](https://stackoverflow.com/a/33556651/3598945) – Rong.l Jan 09 '20 at 10:19

1 Answers1

4

Within the development environment all class files are found in a named folder target (e.g. within Eclipse). The package path is represented as a directory structure. For a directory structure the existance of a Manifest is not defined. Therefore the dedicated class loader will ignore all requests for a Manifest. This is the reason the call returns null.

Running in the productive environment your product is packed within a jar-file. In this case it is defined, that there is a Manifest-file. The jar file class loader knows about the manifest file and will display version information correctly.

What helped us was to provide a default of "Implementation Version" if the version is retrieved within the development environment.

granadaCoder
  • 26,328
  • 10
  • 113
  • 146
Matthias Brenner
  • 372
  • 1
  • 3
  • 10