I have a web app that I've been deploying on both Tomcat and Resin without
any problems for the past several weeks. Originally, I was performing a JNDI
lookup for a DataSource whenever I needed a database connection (ie.
whenever an HTTP request came in). To improve performance, I decided to move
the JNDI lookup to a ServletContextListener (in the contextInitialized
method). 

My DataSource was bound under key java:comp/env/jdbc/OracleDB

When I ran my modified code on Resin, everything worked just fine. However,
when I ran it on Tomcat, I got a NameNotFoundException telling me that
'jdbc' wasn't defined in the context (java:comp/env). I couldn't find any
obvious cause for the problem, since the only change I made to both my
Tomcat and Resin configurations was adding the ServletContextListener. So, I
wrote another ServletContextListener to enumerate all the bindings in my
JNDI context. 

Running my new ServletContextListener on Resin produced the following
output:

The following bindings were found in java:comp/env:
jdbc: [ContextImpl jdbc]
servlet: [ContextImpl servlet]
caucho: [ContextImpl caucho]
ejb: [ContextImpl ejb]
Context enumerated.
The following bindings were found in java:comp/env/jdbc:
OracleDB: [DBPool jdbc/OracleDB]
test: [DBPool jdbc/test]
projman: [DBPool jdbc/projman]
Context enumerated.

Running the same code on Tomcat produced this:

The following bindings were found in java:comp/env:
Context enumerated.
javax.naming.NameNotFoundException: Name jdbc is not bound in this Context
        at
org.apache.naming.NamingContext.listBindings(NamingContext.java:438)
        ...
        (stack trace follows)

Now, I don't expect to see the same set of bindings on Tomcat as I do on
Resin. However, I do expect to see *some* bindings on Tomcat. Unfortunately,
as far as I can tell, my Tomcat JNDI directory is completely empty at the
time in the lifecycle that ServletContextListener.contextInitialized is
called. My expectation would be for JNDI to contain all of the global and
application-specific bindings *before* a ServletContextListener is called
(this is the way Resin behaves). Is this expectation incorrect?

So, here are my questions:

1. Has anyone else run into this same problem?
2. Is this actually a problem, or have I just run into a part of the spec of
which I was previously ignorant?
3. Am I just doing something stupid in my configuration?

Here are the relevant portions of the various files in question:

server.xml:

        ...
     <DefaultContext debug="99">
          <Resource name="jdbc/OracleDB" auth="Container"
               type="javax.sql.DataSource"/> 
          <ResourceParams name="jdbc/OracleDB">
        ...
          </ResourceParams>
     </DefaultContext>
        ...

web.xml:

        ...
     <listener>
 
<listener-class>edu.stanford.irt.mesa.bootstrap.JndiBindingsEnumerationServl
etContextListener</listener-class>
     </listener>
        ...

JndiBindingsEnumerationServletContextListener.java:

public class JndiBindingsEnumerationServletContextListener implements
ServletContextListener 
{
  private void printBindings(Context rootContext, String subContextName) 
    throws NamingException
  {
    NamingEnumeration names = rootContext.listBindings(subContextName);
    System.out.println("The following bindings were found in " +
subContextName + ":");
    while (names.hasMore()) {
      Binding binding = (Binding)names.next();
      String name = binding.getName();
      Object o = binding.getObject();
      System.out.println(name + ": " + o);
    }
    System.out.println("Context enumerated.");    
  }

  /**
   * @see
javax.servlet.ServletContextListener#contextInitialized(ServletContextEvent)
   */
  public void contextInitialized(ServletContextEvent event) 
  {
    try {
      Context context = new InitialContext();
      this.printBindings(context, "java:comp/env");
      this.printBindings(context, "java:comp/env/jdbc");
    }
    catch (NamingException e) {
      e.printStackTrace();
    }
  }

  /**
   * @see
javax.servlet.ServletContextListener#contextDestroyed(ServletContextEvent)
   */
  public void contextDestroyed(ServletContextEvent event) 
  {
  }
}

You will notice right away that I do not have a resource-ref in web.xml. I
contend that I've never needed it before and don't see why I would need it
now.

Thanks in advance for any help,

Jason Axtell
[EMAIL PROTECTED]
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to