I'm facing one odd issue with loading a properties file from a static class/method which is inside a jar file. This jar file is part of a spring boot application. So basically following is the structure
API-springboot.jar
|
|---- BOOT-INF/lib/my-other.jar
|
|----- app.properties
|----- com/foo/bar/blah/Utils.class --> Static class loading app.properties
- Here
Utils.classis a collection of various static utility methods. Util.classhas a static method which loads theapp.properties. Below is the code ofUtils
package com.foo.bar.blah;
public final class Utils {
private static final String PROPS_FILE = "app.properties";
private static final Properties props = loadProperties();
public static String doSomething(String str) {
// ... some logic by reading props
return "blah";
}
private static Properties loadProperties() {
LOG.debug("Loading properties {}", PROPS_FILE);
InputStream resourceAsStream = Thread.currentThread()
.getContextClassLoader()
.getResourceAsStream(PROPS_FILE);
if (resourceAsStream == null) {
throw new RuntimeException("Can't load the properties file " + PROPS_FILE);
}
Properties properties = new Properties();
try {
properties.load(new InputStreamReader(resourceAsStream, StandardCharsets.UTF_8));
} catch (IOException e) {
LOG.error(e.getMessage(), e);
throw new RuntimeException(e);
}
return properties;
}
}
Now when the
Utils.doSomethingis invoked for the first time,loadPropertieswill be invoked and loadapp.properties(at the root of the classpath)This works fine locally (macOS & OpenJDK 11.0.8) and also on my
testenv (RHEL 7 and OpenJDK 11.0.9)When deployed on
UATenv, it cannot findapp.propertiesand throws an exception as defined in the method
if (resourceAsStream == null) {
throw new RuntimeException("Can't load the properties file " + PROPS_FILE);
}
Spring boot version is
v2.3.5.RELEASEBelow is what I've checked till now
- On
UAT, I have the same JRE as ontest UATandtesthas the same version of the application deployed via CI/CD pipeline (Jenkins/Artifactory etc)- On
UAT, I extracted my application's spring-boot jar file and can see themy-other.jarunderBOOT-INF/lib - I verified that
my-other.jarhas theapp.propertiesin the root and also theUtils.classis present - I created a sample test class on one of the
UATservers which simply callsUtils.doSomething("blah")with correct classpath set and it can load theapp.propertiesfrom the jar and shows expected result. But the issue comes when it's invoked from the spring-boot application. - JRE version is the same on
UATandtestand spring-boot application is using the right JRE.
- On
openjdk version "11.0.9" 2020-10-20 LTS
OpenJDK Runtime Environment 18.9 (build 11.0.9+11-LTS)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.9+11-LTS, mixed mode, sharing)
Question: What is causing this behaviour? Am I missing anything? Spent 3 hours with no success.