Bug 38337 - GlobalNamingResource will not allow commercial DataSource drivers
Summary: GlobalNamingResource will not allow commercial DataSource drivers
Status: RESOLVED INVALID
Alias: None
Product: Tomcat 5
Classification: Unclassified
Component: Unknown (show other bugs)
Version: 5.5.12
Hardware: All Windows Server 2003
: P2 critical (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-01-20 21:33 UTC by Berin Loritsch
Modified: 2006-04-13 16:02 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Berin Loritsch 2006-01-20 21:33:43 UTC
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.
Comment 1 Geoffrey Doret 2006-01-22 14:18:07 UTC
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"

Comment 2 Berin Loritsch 2006-01-23 18:23:02 UTC
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.
Comment 3 Berin Loritsch 2006-01-23 18:49:08 UTC
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.
Comment 4 Geoffrey Doret 2006-01-24 00:01:31 UTC
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.
Comment 5 Berin Loritsch 2006-01-24 15:02:59 UTC
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.
Comment 6 Yoav Shapira 2006-04-13 21:02:00 UTC
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.
Comment 7 Berin Loritsch 2006-04-13 21:46:12 UTC
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.
Comment 8 Remy Maucherat 2006-04-13 23:02:31 UTC
(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.