We have the same datasource configurations for three webapps that we host on the same server. We want to merge those configurations into one place with GlobalNamingResource. The exact same configuration in the <Context> element will not work with the <GlobalNamingResource> element. Here is an example Resource config: <!-- NOTE: there are more configuration settings but this is the part that is important --> <Resource name="jdbc/cableds" auth="Container" type="com.jnetdirect.jsql.JSQLPoolingDataSource" factory="org.apache.naming.factory.BeanFactory" serverName="ntncdsql3s" portNumber="1433"/> When that configuration lives inside a <Context> element everything works as expected. When it lives inside a <GlobalNamingResource> Tomcat tries to use the DBCP driver with the exception thrown: org.apache.tomcat.dbcp.dbcp.SQLNestedException: Canot create JDBC driver of class '' for connect URL 'null' .... stack trace omitted .... We do not want to use DBCP, we want to use the JNetDirect pooling drivers we paid for. Why is this happening? We are using Tomcat 5.5.12 (sorry there was no entry for it here) on Windows. This seriously affects our deployment model as we will need to use the same connections for server authentication in the very near future.
The tomact GlobalNamingResources documentation (http://tomcat.apache.org/tomcat-5.5-doc/config/globalresources.html) says: "The GlobalNamingResources element defines the global JNDI resources for the Server. These resources are listed in the server's global JNDI resource context. This context is distinct from the per-web-application JNDI contexts described in the JNDI Resources HOW-TO. The resources defined in this element are not visible in the per-web-application contexts unless you explicitly link them with <ResourceLink> elements." Try to add a ResourceLink in the context.xml file of each web application. For example: <ResourceLink name="jdbc/cabledslink" global="jdbc/cableds" type="com.jnetdirect.jsql.JSQLPoolingDataSource"
OK, I did not see that in the documentation. It worked, so I would recommend updating the Tomcat JNDI Resources How-To to make that part much more obvious.
There is still a bug in that the local Context recgnized the name, although the settings were isolated. Instead, the local context JNDI implementation should have thrown a javax.naming.NameNotFoundException instead.
It's not sure. The SQLNestedException is a subclass containing another Throwable. That other throwable is perhaps a NullPointerException if they don't throw explicitely an Exception during the DataSource intialization. try { InitialContext ctx = new InitialContext(); ds = (DataSource)ctx.lookup("java:comp/env/jdbc/MySQL"); } catch(NamingException e) { // The next line is frequently forgotten. throw new ServletException(e); } To be sure it's a true bug, we need the complete stack trace.
The original issue I had was that a global naming resource appeared as if it would not allow me to use the driver when the resource was declared in <GlobalNamingResource/> and not <Context/>. Thanks to Geoffery's input I found I needed to use a <ResourceLink/> in the context because the app's context and global context were isolated. The problem is that if they _are_ isolated then resource names bound in the <GlobalNamingResource/> should not be recognized in your application <Context/>. They are being recognized and instead of the expected javax.naming.NameNotFoundException I got the NullPointerException. The NullPointerException is completely understandable because I never provide the driver class in the <Resource/> definition because I am not using DBCP. It is troubling that the local app context is trying to resolve the name that should _not_ exist.
Updating version to 5.5.12. We'd also be happy to evaluate and commit any updated documentation text you want. We've had a number of people add stuff to make the ResourceLink requirement clearer, but docs are never perfect as you know ;) As to the actual remaining issue of trying to resolve a non-existant name: I agree it's misleading. I'd like to fix it, but I don't want to throw an NPE (basically, ever). Not sure as to the best fix and don't have time right now to dig deeper. Setting this issue to NEEDINFO status pending submission of documentation change requests and/or patches to deal with the underlying issue.
For names that aren't in a JNDI context, throw the javax.naming.NameNotFoundException The NPE I experienced was within the JTDS driver, so I don't think there is much you can do there.
(In reply to comment #5) > The original issue I had was that a global naming resource appeared as if it > would not allow me to use the driver when the resource was declared in > <GlobalNamingResource/> and not <Context/>. Thanks to Geoffery's input I found > I needed to use a <ResourceLink/> in the context because the app's context and > global context were isolated. > > The problem is that if they _are_ isolated then resource names bound in the > <GlobalNamingResource/> should not be recognized in your application <Context/>. > They are being recognized and instead of the expected > javax.naming.NameNotFoundException I got the NullPointerException. The > NullPointerException is completely understandable because I never provide the > driver class in the <Resource/> definition because I am not using DBCP. It is > troubling that the local app context is trying to resolve the name that should > _not_ exist. That's because your resource is also defined in your web.xml, so it exists in JNDI.