getResourceAsStream not loading resource in webapp

18,355

Solution 1

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

Solution 2

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

Solution 3

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.

Share:
18,355

Related videos on Youtube

AI52487963
Author by

AI52487963

Black lives matter. Avid Java programmer who is passionate about clean code. Author of ez-vcard (an open source Java vCard parser) Author of biweekly (an open source Java iCalendar parser) B.S. Computer Science CompTIA A+ certified LinkedIn

Updated on April 19, 2022

Comments

  • AI52487963
    AI52487963 about 2 years

    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.

  • Pointy
    Pointy about 14 years
    The question pretty clearly says that the resource is located in the WEB-INF/classes directory ...
  • Binil Thomas
    Binil Thomas about 14 years
    @stevedbrown, the OP says that the file is packaged along with the WAR, inside WEB-INF/classes.
  • stevedbrown
    stevedbrown about 14 years
    Did you read the first sentence? "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):"
  • AI52487963
    AI52487963 about 14 years
    My countrymen! Thine quarreling doth hurteth my ears! The resource is in the webapp, but it's the library that needs to access the resource.
  • AI52487963
    AI52487963 about 14 years
    Thanks Andy, I tried moving my config file into common/classes, but it didn't work. My webapp is the only webapp that uses this library, so maybe I'll move it into WEB-INF/lib (although would sort of be a pain because I'd have to modify my Maven pom to have it include the JAR).
  • Binil Thomas
    Binil Thomas about 14 years
    @stevedbrown, I am confused - if libraries in Tomcat root libs are unable to locate classes within a deployed webapp, how does the container load servlets?
  • AI52487963
    AI52487963 about 14 years
    @binil It's not class it's looking for in this case, but a resource that's located in the classpath.
  • Andy Gherna
    Andy Gherna about 14 years
    It's better to keep all the jars in your webapp. Most of the time this is possible, but there are circumstances where moving things into common/lib (like if you're making a resource that's intended to be available across the server).
  • Binil Thomas
    Binil Thomas about 14 years
    @mangst Agreed, but I think the process is the same. I think when looking for the class some.package.FooServlet, it first looks up a resource some/package/FooServlet.class and then loads the bytecode in that file.
  • stevedbrown
    stevedbrown about 14 years
    Andy Gherna took the time to link the Tomcat doc - it explains how Tomcat class loading works. +1'd him, it's a bit more of a full explanation than mine.