0

I am trying a simple web application in tomcat 7. It has a javascript call in the index.html which loads a properties file. Using the below code to make a get call,

var req = new XMLHttpRequest();
req.open("GET", "xyz.properties");
req.onreadystatechange = function() {
    if (req.readyState == 4) {
        if (req.status == 200) {
        }
    }
}
req.send();

Tried the following usecases,

  1. Kept the properties file directly inside the war file, i.e. outside WEB-INF - This works.
  2. Kept it under WEB-INF/classes - Did not work.
  3. Wrapped it in a jar and kept it under WEB-INF/lib - Did not work.
  4. Put the jar under Tomcat/lib - Did not work.

As far as i understand, every resource/class request goes through the WebAppClassloader, which look at things in the following order,

  1. Jvm Boot Strap
  2. system loader
  3. web-inf/classes
  4. web-inf/lib
  5. shared/lib

In my actual application i am using an embedded tomcat and the goal is to externalize(out side of the war) the property file via a jar. Hence the above tests to understand the basic resource loading for tomcat.

Can someone throw some light around what's missing with the above tests. Typically if the get request goes through the class loader, shouldn't it be able to find the file in all cases.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
Victor
  • 1,207
  • 2
  • 13
  • 21

1 Answers1

1

As far as i understand, every resource/class request goes through the WebAppClassloader, which look at things in the following order ...

Yes and no.

Yes, that is what happens when webapp code (or whatever) attempts to locate a resource via the classloader using Class.getResource or equivalent.

But that is NOT what happens when you just send a GET request to your webapp. A GET request doesn't involve the classloader at all. Rather, it must be handled by a servlet; e.g. one that you wrote yourself, one that was generated from a JSP, or the "default" servlet ... which can be used to serve up content files.

Assuming that you want to serve up the properties file that is located via the classloader, your servlet's doRequest or doGet method needs to:

  • find the resource, and open it as an input stream,
  • open the request output stream
  • copy the input stream to the output stream, and then
  • close the input stream.

If you do this, the method needs to make sure it only serves up the specific resources you want to. It would be a really bad idea to allow the client to fetch any resource that the classloader can find.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • I thought, the container will OOB use the classloader to load resources. But apparently from your explaination, this isn't so. Then does it just try to look for relative path of that resource in the web archive? And as for classloader, to use it, one will have to explicitly invoke it via a servlet/filter/etc. – Victor Aug 26 '14 at 12:34