Search code examples
jnditomcat9

Tomcat Reports Resource Name Lookup Error on startup


I have several containerized applications which run in numerous locations. The application containers are based on a Tomcat container then customized accordingly for the application. Each application makes a connection to a containerized mariadb instance co-located on the same server. The JNDI Resource for the database connection is specified globally in the respective web app container server.xml.

In one location, one of the applications connects just fine to the mariadb container while the second application throws a NamingContext.lookup error immediately when tomcat starts.

I have verified the global resource is exactly the same between the applications. I also verified the resource config is the same in both applications webapp_root/META-INF/context.xml.

Here are the relevant parts:

NOTE: All variable values are defined and supplied for the respective catalina.properties file and the values are the same

Application A JNDI Resource definition for server.xml

<Resource name="jdbc/menudb"
        auth="Container"
        driverClassName="com.mysql.cj.jdbc.Driver"
        initialSize="25" 
        logAbandoned="true" 
        minEvictableIdleTimeMillis="30000" 
        minIdle="10" 
        maxActive="50" 
        maxIdle="20" 
        maxWait="1000" 
        removeAbandonedOnBorrow="true" 
        removeAbandonedOnMaintenance="true" 
        removeAbandonedTimeout="15" 
        testOnBorrow="true" 
        testWhileIdle="true" 
        timeBetweenEvictionRunsMillis="300000" 
        type="javax.sql.DataSource" 
        username="${mfg.jdbc.menudb.user}"
        password="${mfg.jdbc.menudb.password}"
        url="${mfg.jdbc.menudb.url}"/>

Application B JNDI Resource definition for server.xml

<Resource name="jdbc/menudb"
        auth="Container"
        driverClassName="com.mysql.cj.jdbc.Driver"
        initialSize="25" 
        logAbandoned="true" 
        minEvictableIdleTimeMillis="30000" 
        minIdle="10" 
        maxActive="50" 
        maxIdle="20" 
        maxWait="1000" 
        removeAbandonedOnBorrow="true" 
        removeAbandonedOnMaintenance="true" 
        removeAbandonedTimeout="15" 
        testOnBorrow="true" 
        testWhileIdle="true" 
        timeBetweenEvictionRunsMillis="300000" 
        type="javax.sql.DataSource"
        username="${mfg.jdbc.menudb.user}"
        password="${mfg.jdbc.menudb.password}"
        url="${mfg.jdbc.menudb.url}"/>

Application A Context.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context docBase="mfgweb" path="/..." reloadable="true" swallowOutput="true">
    <ResourceLink global="jdbc/menudb" name="jdbc/menudb" type="javax.sql.DataSource" />
    <ResourceLink global="localas400" name="localas400" type="javax.sql.DataSource" />
    <ResourceLink global="corpas400" name="corpas400" type="javax.sql.DataSource" />
    <ResourceLink global="gaims" name="gaims" type="javax.sql.DataSource" />
</Context>

Application B Context.xml

<?xml version="1.0" encoding="UTF-8"?>

<Context docBase="menuadmin" path="/..." privileged="true" debug="4" crossContext="true">
    <ResourceLink name="jdbc/menudb" global="jdbc/menudb" type="javax.sql.DataSource" />
</Context>

NOTE: Application A utilizes additional JNDI connections, but the entry for jdbc/menudb are the same.

Here is the full error recorded in Application B docker log

12-Aug-2021 15:41:10.997 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version name:   Apache Tomcat/9.0.21
12-Aug-2021 15:41:11.017 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built:          Jun 4 2019 20:19:36 UTC
12-Aug-2021 15:41:11.018 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version number: 9.0.21.0
12-Aug-2021 15:41:11.018 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name:               Linux
12-Aug-2021 15:41:11.018 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version:            3.10.0-693.21.1.el7.x86_64
12-Aug-2021 15:41:11.018 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture:          amd64
12-Aug-2021 15:41:11.018 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home:             /usr/local/openjdk-8/jre
12-Aug-2021 15:41:11.018 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version:           1.8.0_212-b04
12-Aug-2021 15:41:11.018 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor:            Oracle Corporation
12-Aug-2021 15:41:11.018 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE:         /usr/local/tomcat
12-Aug-2021 15:41:11.018 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME:         /usr/local/tomcat
12-Aug-2021 15:41:11.019 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties
12-Aug-2021 15:41:11.019 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
12-Aug-2021 15:41:11.019 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.library.path=/usr/lib
12-Aug-2021 15:41:11.019 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.awt.headless=true
12-Aug-2021 15:41:11.019 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djavax.net.ssl.trustStore=/usr/local/tomcat/conf/cacerts
12-Aug-2021 15:41:11.019 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djavax.net.ssl.trustStorePassword=***
12-Aug-2021 15:41:11.019 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.security.auth.login.config=/usr/local/tomcat/conf/jaas.config
12-Aug-2021 15:41:11.020 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.security.egd=file:/dev/./urandom
...
12-Aug-2021 15:41:11.020 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -javaagent:/usr/local/tomcat/lib/applicationinsights-agent-2.5.1.jar
12-Aug-2021 15:41:11.020 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.ephemeralDHKeySize=2048
12-Aug-2021 15:41:11.020 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources
12-Aug-2021 15:41:11.020 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dorg.apache.catalina.security.SecurityListener.UMASK=0027
12-Aug-2021 15:41:11.020 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dignore.endorsed.dirs=
12-Aug-2021 15:41:11.020 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=/usr/local/tomcat
12-Aug-2021 15:41:11.021 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=/usr/local/tomcat
12-Aug-2021 15:41:11.021 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=/usr/local/tomcat/temp
12-Aug-2021 15:41:11.632 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]
12-Aug-2021 15:41:11.682 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["ajp-nio-8009"]
12-Aug-2021 15:41:11.684 INFO [main] org.apache.catalina.startup.Catalina.load Server initialization in [1,416] milliseconds
12-Aug-2021 15:41:11.721 WARNING [main] org.apache.naming.NamingContext.lookup Unexpected exception resolving reference
        java.lang.NullPointerException
                at org.apache.naming.factory.ResourceFactory.getDefaultFactory(ResourceFactory.java:45)
                at org.apache.naming.factory.FactoryBase.getObjectInstance(FactoryBase.java:90)
                at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:321)
                at org.apache.naming.NamingContext.lookup(NamingContext.java:840)
                at org.apache.naming.NamingContext.lookup(NamingContext.java:159)
                at org.apache.naming.NamingContextBindingsEnumeration.nextElementInternal(NamingContextBindingsEnumeration.java:117)
                at org.apache.naming.NamingContextBindingsEnumeration.next(NamingContextBindingsEnumeration.java:71)
                at org.apache.naming.NamingContextBindingsEnumeration.next(NamingContextBindingsEnumeration.java:34)
                at org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans(GlobalResourcesLifecycleListener.java:127)
                at org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans(GlobalResourcesLifecycleListener.java:134)
                at org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans(GlobalResourcesLifecycleListener.java:101)
                at org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.lifecycleEvent(GlobalResourcesLifecycleListener.java:76)
                at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123)
                at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:423)
                at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:366)
                at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:925)
                at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
                at org.apache.catalina.startup.Catalina.start(Catalina.java:633)
                at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
                at java.lang.reflect.Method.invoke(Method.java:498)
                at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:344)
                at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:475)
12-Aug-2021 15:41:11.722 SEVERE [main] org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans Exception processing global JNDI Resources
        javax.naming.NamingException: Unexpected exception resolving reference [Root exception is java.lang.NullPointerException]
                at org.apache.naming.NamingContext.lookup(NamingContext.java:856)
                at org.apache.naming.NamingContext.lookup(NamingContext.java:159)
                at org.apache.naming.NamingContextBindingsEnumeration.nextElementInternal(NamingContextBindingsEnumeration.java:117)
                at org.apache.naming.NamingContextBindingsEnumeration.next(NamingContextBindingsEnumeration.java:71)
                at org.apache.naming.NamingContextBindingsEnumeration.next(NamingContextBindingsEnumeration.java:34)
                at org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans(GlobalResourcesLifecycleListener.java:127)
                at org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans(GlobalResourcesLifecycleListener.java:134)
                at org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans(GlobalResourcesLifecycleListener.java:101)
                at org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.lifecycleEvent(GlobalResourcesLifecycleListener.java:76)
                at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123)
                at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:423)
                at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:366)
                at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:925)
                at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
                at org.apache.catalina.startup.Catalina.start(Catalina.java:633)
                at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
                at java.lang.reflect.Method.invoke(Method.java:498)
                at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:344)
                at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:475)
        Caused by: java.lang.NullPointerException
                at org.apache.naming.factory.ResourceFactory.getDefaultFactory(ResourceFactory.java:45)
                at org.apache.naming.factory.FactoryBase.getObjectInstance(FactoryBase.java:90)
                at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:321)
                at org.apache.naming.NamingContext.lookup(NamingContext.java:840)
                ... 20 more
12-Aug-2021 15:41:11.887 WARNING [main] com.hazelcast.config.AbstractXmlConfigHelper.null Name of the hazelcast schema location is incorrect, using default
12-Aug-2021 15:41:12.063 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina]
12-Aug-2021 15:41:12.063 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet engine: [Apache Tomcat/9.0.21]
12-Aug-2021 15:41:12.100 INFO [main] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive [/usr/local/tomcat/webapps/****.war]

Does anyone see a reason why Application A works and can connect to the database just fine while Application B reports it cannot find the resource due to a Null Pointer exception?

This is extremely frustrating and this particular location has been without the use of Application B for a few months now.


Solution

  • For Tomcat 9 you need to define the correct factory for the resource, e.g.:

    <Resource name="jdbc/menudb"
        auth="Container"
        driverClassName="com.mysql.cj.jdbc.Driver"
        initialSize="25" 
        logAbandoned="true" 
        minEvictableIdleTimeMillis="30000" 
        minIdle="10" 
        maxActive="50" 
        maxIdle="20" 
        maxWait="1000" 
        removeAbandonedOnBorrow="true" 
        removeAbandonedOnMaintenance="true" 
        removeAbandonedTimeout="15" 
        testOnBorrow="true" 
        testWhileIdle="true" 
        timeBetweenEvictionRunsMillis="300000" 
        username="${mfg.jdbc.menudb.user}"
        password="${mfg.jdbc.menudb.password}"
        url="${mfg.jdbc.menudb.url}"
    
        jdbcInterceptors="StatementCache"
        factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
        type="org.apache.tomcat.jdbc.pool.DataSource"
    />