Hi everybody, I have found a strange behavior on Tomcat 9.0.5 (originally on Tomcat 8.5.28).
# PROBLEM I have two datasources in the same web application: <ResourceLink global="jdbc/abc/ABC" name="jdbc/abc" type="javax.sql.DataSource"/> <ResourceLink global="jdbc/abc/jkl/XXX_YYY" name="jdbc/abc/jkl" type="javax.sql.DataSource"/> Starting the server I get an "java.lang.ClassCastException: org.apache.tomcat.dbcp.dbcp2.BasicDataSource cannot be cast to javax.naming.Context" ERROR. # HOW TO REPRODUCE THE ERROR In my Apache Tomcat 9.0.5's server.xml: <GlobalNamingResources> <Resource name="jdbc/abc/ABC" type="javax.sql.DataSource" driverClassName="oracle.jdbc.OracleDriver" url="jdbc:oracle:thin:@machine1:1678:DEV" auth="Container" username="ABC" password="**************************************" maxTotal="8" maxIdle="4" logAbandoned="true" /> <Resource name="jdbc/abc/jkl/XXX_YYY" type="javax.sql.DataSource" driverClassName="oracle.jdbc.OracleDriver" url="jdbc:oracle:thin:@machine1:1678:DEV" auth="Container" username="XXX_YYY" password="**************************************" maxTotal="8" maxIdle="4" logAbandoned="true" /> </GlobalNamingResources> In C:\my-favourite-ide\abc\src\main\webapp\META-INF\context.xml (it's an Apache Maven project): <?xml version="1.0" encoding="UTF-8"?> <Context useHttpOnly="true" path="/abc"> <!-- "global" attribute links to GlobalNamingResources in the ${catalina.base}/conf/server.xml (server administrator team) "name" attribute is relative to the JNDI context java:comp/env/ and is looked up from the java application (application developer team) --> <ResourceLink global="jdbc/abc/ABC" name="jdbc/abc" type="javax.sql.DataSource"/> <ResourceLink global="jdbc/abc/jkl/XXX_YYY" name="jdbc/abc/jkl" type="javax.sql.DataSource"/> </Context> In C:\my-favourite-ide\abc\src\main\webapp\WEB-INF\web.xml: <resource-ref> <description>Datasource ofv</description> <res-ref-name>jdbc/abc</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref> <resource-ref> <description>Datasource ofv</description> <res-ref-name>jdbc/abc/jkl</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref> Starting the server I get the "java.lang.ClassCastException: org.apache.tomcat.dbcp.dbcp2.BasicDataSource cannot be cast to javax.naming.Context" ERROR: Using CATALINA_BASE: "C:\java\apache-tomcat-9.0.5-catalina-base" Using CATALINA_HOME: "C:\java\apache-tomcat-9.0.5" Using CATALINA_TMPDIR: "C:\java\apache-tomcat-9.0.5-catalina-base\temp" Using JRE_HOME: "C:\java\jdk1.8.0_111" Using CLASSPATH: "C:\java\apache-tomcat-9.0.5\bin\bootstrap.jar;C:\java\apache-tomcat-9.0.5\bin\tomcat-juli.jar" 06-Mar-2018 10:23:07.968 WARN [main] org.apache.catalina.startup.VersionLoggerListener.log Server version: Apache Tomcat/9.0.5 06-Mar-2018 10:23:07.984 WARN [main] org.apache.catalina.startup.VersionLoggerListener.log Server built: Feb 6 2018 21:42:23 UTC 06-Mar-2018 10:23:07.984 WARN [main] org.apache.catalina.startup.VersionLoggerListener.log Server number: 9.0.5.0 06-Mar-2018 10:23:07.984 WARN [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name: Windows 7 06-Mar-2018 10:23:07.984 WARN [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version: 6.1 06-Mar-2018 10:23:07.984 WARN [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture: amd64 06-Mar-2018 10:23:07.984 WARN [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home: C:\java\jdk1.8.0_111\jre 06-Mar-2018 10:23:07.984 WARN [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version: 1.8.0_111-b14 06-Mar-2018 10:23:07.984 WARN [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor: Oracle Corporation 06-Mar-2018 10:23:07.984 WARN [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE: C:\java\apache-tomcat-9.0.5-catalina-base 06-Mar-2018 10:23:07.984 WARN [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME: C:\java\apache-tomcat-9.0.5 06-Mar-2018 10:23:07.984 WARN [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=C:\java\apache-tomcat-9.0.5-catalina-base\conf\logging.properties 06-Mar-2018 10:23:07.984 WARN [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager 06-Mar-2018 10:23:07.984 WARN [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.ephemeralDHKeySize=2048 06-Mar-2018 10:23:07.984 WARN [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources 06-Mar-2018 10:23:07.984 WARN [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dignore.endorsed.dirs= 06-Mar-2018 10:23:07.984 WARN [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=C:\java\apache-tomcat-9.0.5-catalina-base 06-Mar-2018 10:23:07.984 WARN [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=C:\java\apache-tomcat-9.0.5 06-Mar-2018 10:23:07.984 WARN [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=C:\java\apache-tomcat-9.0.5-catalina-base\temp 06-Mar-2018 10:23:07.984 WARN [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent Loaded APR based Apache Tomcat Native library [1.2.16] using APR version [1.6.3]. 06-Mar-2018 10:23:07.984 WARN [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true]. 06-Mar-2018 10:23:07.984 WARN [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true] 06-Mar-2018 10:23:08.545 WARN [main] org.apache.catalina.core.AprLifecycleListener.initializeSSL OpenSSL successfully initialized [OpenSSL 1.0.2m 2 Nov 2017] 06-Mar-2018 10:23:08.920 WARN [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"] 06-Mar-2018 10:23:08.966 WARN [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read 06-Mar-2018 10:23:08.966 WARN [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["ajp-nio-8009"] 06-Mar-2018 10:23:08.966 WARN [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read 06-Mar-2018 10:23:08.966 WARN [main] org.apache.catalina.startup.Catalina.load Initialization processed in 1349 ms 06-Mar-2018 10:23:08.998 WARN [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina] 06-Mar-2018 10:23:08.998 WARN [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet Engine: Apache Tomcat/9.0.5 06-Mar-2018 10:23:09.029 WARN [main] org.apache.catalina.startup.HostConfig.deployDescriptor Deploying configuration descriptor [C:\java\apache-tomcat-9.0.5-catalina-base\conf\Catalina\localhost\manager.xml] 06-Mar-2018 10:23:09.668 WARN [main] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time. 06-Mar-2018 10:23:09.715 WARN [main] org.apache.catalina.startup.HostConfig.deployDescriptor Deployment of configuration descriptor [C:\java\apache-tomcat-9.0.5-catalina-base\conf\Catalina\localhost\manager.xml] has finished in [686] ms 06-Mar-2018 10:23:09.715 WARN [main] org.apache.catalina.startup.HostConfig.deployDescriptor Deploying configuration descriptor [C:\java\apache-tomcat-9.0.5-catalina-base\conf\Catalina\localhost\abc.xml] 06-Mar-2018 10:23:12.773 GRAVE [main] org.apache.catalina.core.ContainerBase.addChildInternal ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/abc]] at org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:441) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:198) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:740) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:716) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:703) at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:619) at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1829) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112) at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:530) at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:429) at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1575) at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:308) at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123) at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:424) at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:367) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:964) at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:839) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1425) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1415) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:941) at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:258) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.StandardService.startInternal(StandardService.java:422) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:770) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.startup.Catalina.start(Catalina.java:682) 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:353) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:493) Caused by: java.lang.ClassCastException: org.apache.tomcat.dbcp.dbcp2.BasicDataSource cannot be cast to javax.naming.Context at org.apache.catalina.core.NamingContextListener.createSubcontexts(NamingContextListener.java:1310) at org.apache.catalina.core.NamingContextListener.addResourceLink(NamingContextListener.java:1156) at org.apache.catalina.core.NamingContextListener.createNamingContext(NamingContextListener.java:655) at org.apache.catalina.core.NamingContextListener.lifecycleEvent(NamingContextListener.java:249) at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4997) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ... 38 more 06-Mar-2018 10:23:12.898 GRAVE [main] org.apache.catalina.startup.HostConfig.deployDescriptor Error deploying configuration descriptor [C:\java\apache-tomcat-9.0.5-catalina-base\conf\Catalina\localhost\abc.xml] java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/abc]] at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:744) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:716) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:703) at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:619) at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1829) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112) at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:530) at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:429) at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1575) at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:308) at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123) at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:424) at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:367) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:964) at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:839) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1425) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1415) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:941) at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:258) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.StandardService.startInternal(StandardService.java:422) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:770) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.startup.Catalina.start(Catalina.java:682) 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:353) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:493) 06-Mar-2018 10:23:12.898 WARN [main] org.apache.catalina.startup.HostConfig.deployDescriptor Deployment of configuration descriptor [C:\java\apache-tomcat-9.0.5-catalina-base\conf\Catalina\localhost\abc.xml] has finished in [3,183] ms 06-Mar-2018 10:23:12.898 WARN [main] org.apache.catalina.startup.HostConfig.deployDescriptor Deploying configuration descriptor [C:\java\apache-tomcat-9.0.5-catalina-base\conf\Catalina\localhost\ROOT.xml] 06-Mar-2018 10:23:13.475 WARN [main] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time. 06-Mar-2018 10:23:13.475 WARN [main] org.apache.catalina.startup.HostConfig.deployDescriptor Deployment of configuration descriptor [C:\java\apache-tomcat-9.0.5-catalina-base\conf\Catalina\localhost\ROOT.xml] has finished in [577] ms 06-Mar-2018 10:23:13.475 WARN [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"] 06-Mar-2018 10:23:13.490 WARN [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"] 06-Mar-2018 10:23:13.490 WARN [main] org.apache.catalina.startup.Catalina.start Server startup in 4521 ms ## NOTES The error seems realted only to ResourceLink's "name" attribute, and not to "global" attribute, in server.xml: ERROR <ResourceLink global="jdbc/abc/ABC" name="jdbc/abc" type="javax.sql.DataSource"/> <ResourceLink global="jdbc/abc/jkl/XXX_YYY" name="jdbc/abc/jkl" type="javax.sql.DataSource"/> The error disappears with the following "name" attribute values (of course when I change the "name" attribute value I change accordingly the "<res-ref-name>" tag body in the web.xml): WORKS FINE <ResourceLink global="jdbc/abc/ABC" name="jdbc/abc" type="javax.sql.DataSource"/> <ResourceLink global="jdbc/abc/jkl/XXX_YYY" name="jdbc/abx/jkl" type="javax.sql.DataSource"/> WORKS FINE <ResourceLink global="jdbc/abc/ABC" name="jdbc/abc" type="javax.sql.DataSource"/> <ResourceLink global="jdbc/abc/jkl/XXX_YYY" name="jdbc/axc/jkl" type="javax.sql.DataSource"/> WORKS FINE <ResourceLink global="jdbc/abc/ABC" name="jdbc/abc" type="javax.sql.DataSource"/> <ResourceLink global="jdbc/abc/jkl/XXX_YYY" name="jdbc/xbc/jkl" type="javax.sql.DataSource"/> WORKS FINE <ResourceLink global="jdbc/abc/ABC" name="jdbc/abc" type="javax.sql.DataSource"/> <ResourceLink global="jdbc/abc/jkl/XXX_YYY" name="jdbc/aabc/jkl" type="javax.sql.DataSource"/> WORKS FINE <ResourceLink global="jdbc/abc/ABC" name="jdbc/abc" type="javax.sql.DataSource"/> <ResourceLink global="jdbc/abc/jkl/XXX_YYY" name="jdbc/abcc/jkl" type="javax.sql.DataSource"/> Thank you very much for your help. Best regards, Tarin www.taringamberini.com/en/blog