开发者

getResourceAsStream not loading resource in webapp

开发者 https://www.devze.com 2022-12-26 21:47 出处:网络
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):

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 metho开发者_C百科d to act differently? I know there's a lot of similar questions out there, but none of them have helped unfortunately. Thanks.


Try Thread.currentThread().getContextClassLoader().getResourceAsStream("/hv-application.properties") instead.


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:

  1. Move the jar file in common/lib into your web application (WEB-INF/lib). This is not always possible I know, but sometimes jars (e.g. log4j) can coexist peacefully across classloaders (*).
  2. Move your configuration file into common/classes. This is effectively the same thing (puts the configuration item into the same classloader as the jar that needs it). Again, this is not ideal, but if you have control over your environment, it would work.

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


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消