Tomcat 8 global DataSource closed before `ServletContextListener.contextDestroyed ()`

I have deployed a web application to Tomcat 8. This application defines a global JNDI DataSource

that is shared by multiple servlets. Inside the application, it is wrapped in a Spring bean that uses a factory method to retrieve this from the JNDI. There is also ServletContextListener

one implemented to react when the web application context is destroyed. The application itself works great and DataSource

can be retrieved and used correctly.

Problem . On completion, Tomcat ( catalina.sh stop

, SIGINT

or SIGTERM

) is DataSource

closed before being called ServletContextListener.contextDestroyed()

. This is bad because I need to access the DB in this method (for example, to properly close our Quartz scheduler, which has access to the database).

Here's a snippet server.xml

:

<Server port="8005" shutdown="SHUTDOWN">
    ...
    <GlobalNamingResources>
        ...
        <Resource name="myDB" auth="Container" type="javax.sql.DataSource"
            maxTotal="100" maxIdle="30" maxWaitMillis="10000" username="" password=""
            removeAbandonedOnBorrow="true" removeAbandonedTimeout="60"  driverClassName="org.h2.Driver"
            url="jdbc:h2:myApp" defaultTransactionIsolation="READ_COMMITTED" />
        ...
    </GlobalNamingResources>
    ...
</Server>

      

Here from context.xml

:

<Context path="/myApp" docBase="myApp"
    reloadable="false" crossContext="false" antiResourceLocking="true" unloadDelay="5000">
    <ResourceLink name="jdbc/myDB" global="myDB" type="javax.sql.DataSource" />
    <Manager className="org.apache.catalina.session.PersistentManager"
        distributable="false" saveOnRestart="false">
        <Store className="org.apache.catalina.session.FileStore"/>
    </Manager>
</Context>

      

Here is a snippet of mine ServletContextListener

:

public class MyListener implements ServletContextListener {
...
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        ...
        // using the DataSource here
        ...
    }
...
}

      

In the logs I see Exception

when I try to use DataSource

in ServletContextListener

, saying that the datasource is already closed:

05 Aug 2015 14:59:17,915 [localhost-startStop-2] () || DEBUG   DisposableBeanAdapter: Invoking destroy method 'close' on bean with name 'dataSource'
05-Aug-2015 14:59:17.918 WARNING [localhost-startStop-2] org.apache.tomcat.dbcp.dbcp2.BasicDataSource.close Failed to unregister the JMX name: Catalina:type=DataSource,class=javax.sql.DataSource,name="myDB"
 javax.management.InstanceNotFoundException: Catalina:type=DataSource,class=javax.sql.DataSource,name="myDB"
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getMBean(Unknown Source)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.exclusiveUnregisterMBean(Unknown Source)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.unregisterMBean(Unknown Source)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.unregisterMBean(Unknown Source)
    at org.apache.tomcat.dbcp.dbcp2.BasicDataSource.close(BasicDataSource.java:1916)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.beans.factory.support.DisposableBeanAdapter.invokeCustomDestroyMethod(DisposableBeanAdapter.java:327)
    at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:253)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:510)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:486)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:742)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:455)
    at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1090)
    at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1064)
    at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:1010)
    at org.springframework.web.context.ContextLoader.closeWebApplicationContext(ContextLoader.java:586)
    at org.springframework.web.context.ContextLoaderListener.contextDestroyed(ContextLoaderListener.java:143)
    at org.apache.catalina.core.StandardContext.listenerStop(StandardContext.java:4776)
    at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5390)
    at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:232)
    at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1424)
    at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1413)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
...
Shutting down scheduler.
...
05 Aug 2015 14:59:24,098 [QuartzScheduler_DefaultQuartzScheduler-4424f282be6c1438786703813_ClusterManager] () || ERROR   JobStoreTX          : ClusterManager: Error managing cluster: Failed to obtain DB connection from data source 'qrtzds': java.sql.SQLException: Could not retrieve datasource via JNDI url 'java:comp/env/jdbc/myDB' java.sql.SQLException: Data source is closed
org.quartz.JobPersistenceException: Failed to obtain DB connection from data source 'qrtzds': java.sql.SQLException: Could not retrieve datasource via JNDI url 'java:comp/env/jdbc/myDB' java.sql.SQLException: Data source is closed [See nested exception: java.sql.SQLException: Could not retrieve datasource via JNDI url 'java:comp/env/jdbc/myDB' java.sql.SQLException: Data source is closed]
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.getConnection(JobStoreSupport.java:778)
    at org.quartz.impl.jdbcjobstore.JobStoreTX.getNonManagedTXConnection(JobStoreTX.java:71)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.doCheckin(JobStoreSupport.java:3245)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport$ClusterManager.manage(JobStoreSupport.java:3858)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport$ClusterManager.run(JobStoreSupport.java:3895)
Caused by: java.sql.SQLException: Could not retrieve datasource via JNDI url 'java:comp/env/jdbc/myDB' java.sql.SQLException: Data source is closed
    at org.quartz.utils.JNDIConnectionProvider.getConnection(JNDIConnectionProvider.java:163)
    at org.quartz.utils.DBConnectionManager.getConnection(DBConnectionManager.java:108)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.getConnection(JobStoreSupport.java:775)
    ... 4 more

      

Question

  • How can I manage the Tomcat lifecycle to close the global resource DataSource

    after destroying the web application context?
  • How can I tell Spring not to use a method BasicDataSource.close()

    ? I tried to set the bean attribute destroy-method

    to empty. But it seems that when it is empty, it still calls the method close()

    because it detectsAutoClosable

    .
+3
java spring tomcat datasource jndi


source to share


No one has answered this question yet

Check out similar questions:

148
How to use the JNDI DataSource provided by Tomcat in Spring?
1
Error creating a component named "entityManagerFactory" defined in the ServletContext resource [/WEB-INF/dispatcher-servlet.xml]:
1
How to close HikariCP JNDI DataSource on shutdown / redeployment
0
NullPointerException while initializing org.springframework.orm.hibernate4.LocalSessionFactoryBean
0
Call to destroy method "close" failed with bean named "mvcValidator"
0
Tomcat 8 Oracle 11 JNDI Unable to create JDBC driver class' to connect url 'null'
0
Spring - 404 when using declarative list
0
Spring boot configure tomcat context.xml datasource
0
How to set up Oracle JNDI datasource on Pivotal TC server?
-1
spring-loaded jdbc hibernation connection



All Articles
Loading...
X
Show
Funny
Dev
Pics