After testing and searching on Spring docs, I found a way to read the manifest file.
First off, Spring Boot implements its own ClassLoader that changes the way how resources are loaded. When you call getResource()
, Spring Boot will load the first resource that matches the given resource name in the list of all JARs available in the class path, and your app jar is not the first choice.
So, when issuing a command like:
getClassLoader().getResourceAsStream("/META-INF/MANIFEST.MF");
The first MANIFEST.MF file found in any Jar of the Class Path is returned. In my case, it came from a JDK jar library.
SOLUTION:
I managed to get a list of all Jars loaded by the app that contains the resource "/META-INF/MANIFEST.MF" and checked if the resource came from my application jar. If so, read its MANIFEST.MF file and return to the app, like that:
private Manifest getManifest() {
// get the full name of the application manifest file
String appManifestFileName = this.getClass().getProtectionDomain().getCodeSource().getLocation().toString() + JarFile.MANIFEST_NAME;
Enumeration resEnum;
try {
// get a list of all manifest files found in the jars loaded by the app
resEnum = Thread.currentThread().getContextClassLoader().getResources(JarFile.MANIFEST_NAME);
while (resEnum.hasMoreElements()) {
try {
URL url = (URL)resEnum.nextElement();
// is the app manifest file?
if (url.toString().equals(appManifestFileName)) {
// open the manifest
InputStream is = url.openStream();
if (is != null) {
// read the manifest and return it to the application
Manifest manifest = new Manifest(is);
return manifest;
}
}
}
catch (Exception e) {
// Silently ignore wrong manifests on classpath?
}
}
} catch (IOException e1) {
// Silently ignore wrong manifests on classpath?
}
return null;
}
This method will return all data from a manifest.mf file inside a Manifest object.
I borrowed part of the solution from reading MANIFEST.MF file from jar file using JAVA