I solved the mystery.
The key to solving was embedding some diagnostic logging when propertiesStream
is null:
String classpath = System.getProperty("java.class.path");
LOG.info("CLASSPATH: " + classpath);
ClassLoader loader = MyClientMain.class.getClassLoader();
System.out.println("ClassLoader resource path: " + loader.getResource("resource.properties"));
So when I run with the original
contextClassLoader.getResourceAsStream("resource.properties")
I receive the null pointer condition, printing:
INFO: CLASSPATH: myproj.one-jar.jar
ClassLoader resource path: null
.
I then started suspecting something related to the "jar within a jar" as this is what the com.simontuffs.onejar essentially does (i.e. wrapping my project's jar inside a jar that contains all other library jars), so I opened myproj.one-jar.jar with 7-Zip and noted the full (absolute) path of "resource.properties":
myproj.one-jar.jar\main\myproj.jar\webapp\WEB-INF\classes\resource.properties
.
So I modified getResource("resource.properties")
to:
getResource("/main/myproj.jar/webapp/WEB-INF/classes/resource.properties")
which didn't fix the problem but printed the following upon the null pointer condition:
INFO: CLASSPATH: myproj.one-jar.jar
ClassLoader resource path: jar:file:/myproj.one-jar.jar!/main/myproj.jar!//main/myproj.jar/webapp/WEB-INF/classes/resource.properties
.
Then... divine intervention fell upon me and I had the insight (not reading any documentation that could even hint this, I swear!) that I should be using this path instead:
getResource("/webapp/WEB-INF/classes/resource.properties")
And Voila! It works.
Whew.