Phantom Resources in Web Applications when Deployed to different Application Servers

When deployed to different application servers, a simple hello.war behaves differently in terms of resource accessing.  It has been a major source of headache when porting apps to support various servers.  This is how the war file looks like:

|   index.jsp
    |   web.xml

Phantom 1: default welcome file list

My web.xml is essentially empty, and its sole purpose is to indicate to target servers that it's a war file.  I'm hoping index.jsp can be used as the default welcome file, even though I don't specify it in web.xml.  So when I access URL http://localhost:8080/hello/, index.jsp should be invoked.  In Glassfish/SJSAS, default welcome file list is defined in $SJSAS_HOME/domains/domain1/config/default-web.xml, and in Tomcat, it's in $CATALINA_HOME/conf/web.xml. In a similar manner, Weblogic looks for index.html, index.htm, and index.jsp and uses the first one it finds, if the webapp doesn't define any welcome files.

This is a snippet from Glassfish's default-web.xml:

<!-- ==================== Default Welcome File List ===================== -->
<!-- When a request URI refers to a directory, the default servlet looks  -->
<!-- for a "welcome file" within that directory and, if present,          -->
<!-- to the corresponding resource URI for display. If no welcome file    -->
<!-- is present, the default servlet either serves a directory listing,   -->
<!-- or returns a 404 status, depending on how it is configured.          -->

<!-- If you define welcome files in your own application's web.xml        -->
<!-- deployment descriptor, that list \*replaces\* the list configured      -->
<!-- here, so be sure that you include any of the default values that     -->
<!-- you wish to include.                                                 -->


This default welcome file list works well on Glassfish/SJSAS, Weblogic 9, Tomcat 5 and Jboss 4.0.4.  However, there is no such default welcome files in Websphere 6.  When accessing http://localhost:9080/hello/, I got status code 404 (Page Not Found).  My first response was, something went wrong when deploying, enabling, and starting the hello webapp.  I couldn't believe such an obvious name (index.jsp) is not recognized as a default welcome file.

It also turns out, Websphere 6 out-of-the-box doesn't map URL http://localhost:9080/ to any default applications, even if the sever is running on port 9080.  Since I have the habit of checking this root URL to verify if the server is running, I felt this is a little inconvenient.  In Tomcat, the default application is at $CATALINA_HOME/webapps/ROOT, and in Glassfish/SJSAS, it is at $SJSAS_HOME/domains/domain1/docroot.

I should also make it clear that this is not a bug in Websphere 6.  Servlet spec leaves this open to vendor implementation (Servlet 2.4 Section 9.10):

If no matching welcome file is found in the manner described, the container may handle the request in a manner it finds suitable. For some configurations this may mean returning a directory listing or for others returning a 404 response.


Phantom 2:  ServletContext.getResourceAsStream(String path)

My index.jsp has some java code snippet, for testing purpose:

    String[] paths = new String[]{"/WEB-INF/resources/",
    for(int i = 0; i < paths.length; i++) {
     InputStream is = null;
     try {
        is = application.getResourceAsStream(paths[i]);
        if(is == null) {
            out.println("failed to get resource: " + paths[i]);
        } else {
            byte[] buffer = new byte[2000];
            out.println("got the resource: " + paths[i] +
                    ", and its content: " + new String(buffer));
     } finally {
       if(is != null) {

On Glassfish/SJSAS, Weblogic 9, Tomcat 5 and Jboss 4.0.4, I was able to retrieve the resource using the path with or without a leading slash:

got the resource: /WEB-INF/resources/, and its content: mysql.driver=com.mysql.jdbc.Driver mysql.url=jdbc:mysql://localhost:3306/sales 
got the resource: WEB-INF/resources/, and its content: mysql.driver=com.mysql.jdbc.Driver mysql.url=jdbc:mysql://localhost:3306/sales

But on Websphere 6, I found I must use the path with a leading slash.  Using a path that doesn't start with a slash, I got a null return value from ServletContext.getResourceAsStream("WEB-INF/resources/").

Again, there is nothing wrong in Websphere server, since ServletContext javadoc says:

The path must begin with a "/" and is interpreted as relative to the current context root... [returns] null if no resource exists at the specified path

But Servlet spec stops short of saying what should happen if the path does not start with a slash.  So we can say it's a bug in my index.jsp.  The reason it worked with Glassfish/SJSAS, Weblogic 9, Tomcat 5 and Jboss 4.0.4, is that it depends on some server-specific features.

While it's comforting to know the above issues are not Websphere 6 bugs, curious minds are wondering why Websphere choose to be different from the 4 other mainstream servers.

technorati tags: , ,


You're awsome. I had Phantom 2 problem when I migrated from WAS 5.1 to WAS6.1. Adding a leading slash fixed it. Thanks.

Posted by PKite on February 26, 2008 at 07:20 AM EST #

Good article and this is still relevant to day in 2009. There are still quite a few open source and commercial products accessing files for within web apps and while this works on many app servers weblogic and websphere soon pick out the issues.

Posted by Steve on November 02, 2009 at 08:56 AM EST #

Post a Comment:
  • HTML Syntax: NOT allowed

Cheng Fang


« July 2016