Reputation: 35341
I have a web application that uses a library which resides in TOMCAT_HOME/common/lib. This library looks for a properties file at the root of the classpath (in a class called ApplicationConfig):
ApplicationConfig.class.getResourceAsStream("/hv-application.properties");
My Tomcat web application contains this properties file. It is in WEB-INF/classes, which is the root of the classpath right? However, at runtime, when it tries to load the properties file, it throws an exception because it can't find it (getResourceAsStream returns null).
Everything works fine if my application is a simple, standalone Java application. Does Tomcat cause the getResourceAsStream method to act differently? I know there's a lot of similar questions out there, but none of them have helped unfortunately. Thanks.
Upvotes: 14
Views: 19417
Reputation: 683
I'm expanding Olivier comment as a response (thank you for the lead).
The problem seems to be the leading slash (/) in the resource path.
In Tomcat 8 the WebAppClassloader correctly resolves the path with and without the leading slash. Both .getResourceAsStream("/org/pakopa/app/config.properties");
and .getResourceAsStream("org/pakopa/app/config.properties");
returns an InputStream.
In Tomcat 7 (And I assume previous versions too) .getResourceAsStream("/org/pakopa/app/config.properties");
is not resolved and returns null
but .getResourceAsStream("org/pakopa/app/config.properties");
is correctly resolved.
Upvotes: 0
Reputation: 2165
This looks like it might be related to how Tomcat classloaders work. If you have something in one class loader (your config file in the webapp classloader) that's used by something in another (the jar in common/lib), the result could be a big headache.
This document explains how Tomcat delegates to class loaders. If possible, could you try one of the following:
Either way, having resources in different classloaders can be a pain. I hope this helps.
(*) log4j has the -log4j.ignoreTCL
option which makes this possible though
Upvotes: 3
Reputation: 8934
The Tomcat security manager generally won't let you access webapp classes and resources from libraries in the Tomcat root libraries. This is meant to give separation between the web applications running in a container.
You should be able to get around this by updating the security policy, but it's generally better to not put your libs into the Tomcat container, which I assume you are doing.
Upvotes: 1
Reputation: 13779
Try Thread.currentThread().getContextClassLoader().getResourceAsStream("/hv-application.properties")
instead.
Upvotes: 24