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.class
is a collection of various static utility methods. Util.class
has 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.doSomething
is invoked for the first time,loadProperties
will be invoked and loadapp.properties
(at the root of the classpath)This works fine locally (macOS & OpenJDK 11.0.8) and also on my
test
env (RHEL 7 and OpenJDK 11.0.9)When deployed on
UAT
env, it cannot findapp.properties
and 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.RELEASE
Below is what I've checked till now
- On
UAT
, I have the same JRE as ontest
UAT
andtest
has 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.jar
underBOOT-INF/lib
- I verified that
my-other.jar
has theapp.properties
in the root and also theUtils.class
is present - I created a sample test class on one of the
UAT
servers which simply callsUtils.doSomething("blah")
with correct classpath set and it can load theapp.properties
from 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
UAT
andtest
and 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.