-----Original Message-----
From: Mark Eggers [mailto:its_toas...@yahoo.com]
Sent: Thursday, April 18, 2013 9:55 PM
To: users@tomcat.apache.org
Subject: Re: Tomcat 7.0 & spring web applcaiton context - Fedora 17
On 4/18/2013 6:35 PM, Khurram Raza wrote:
Hi,
After spending days I am writing my problem on this forum. The problem
is when I undeploy a webapp or shutdown tomcat, spring
WebApplicationContext is closed and spring singleton beans destroyed
before webapp Servlet's destroy() method is called. This leads me to
'java.lang.IllegalStateException' in Servlet's destroy() method where
I am cleaning my resources and destroying dynamically created spring
beans and datasources. This happens with tomcat 7.0.39 only on Linux
(fedora
17) platform. On windows this works perfectly fine on tomcat 7.0.39. I
have also tried my webapp on tomcat-7.0.29 & tomcat 7.0.25 on linux
but the problem persists. I have tried same webapp on tomcat-7.0.29 &
tomcat-7.0.23 on windows and this work fine without any problem. So I
am not sure why it breaks in Linux environment. Here is the log
snippet generated on both Linux and Windows:
Windows (webapp log snippet)
...
2013-04-14 20:33:16,510 INFO [localhost-startStop-2]
com.mycompany.servlet.DSServlet - DSServlet|destroy()
2013-04-14 20:33:16,510 INFO [localhost-startStop-2]
com.mycompany.servlet.DSServlet - Releasing resources...
2013-04-14 20:33:16,510 DEBUG [localhost-startStop-2]
com.mycompany.servlet.DSServlet - Spring application context:
WebApplicationContext for namespace 'contoller-servlet': startup date
[Sun Apr 14 20:32:53 EDT 2013]; root of context hierarchy
2013-04-14 20:33:16,510 DEBUG [localhost-startStop-2]
com.mycompany.servlet.DSServlet - Obtaining 'jdbc_rdb' beans of type
DSBean from the spring application context...
2013-04-14 20:33:16,510 DEBUG [localhost-startStop-2]
com.mycompany.servlet.DSServlet - 'jdbc_rdb' beans obtained from the
spring application context...
2013-04-14 20:33:16,510 DEBUG [localhost-startStop-2]
com.mycompany.servlet.DSServlet - 'jdbc_rdb' beanName:
jdbc_rdb_127.0.0.1
2013-04-14 20:33:16,947 INFO [localhost-startStop-2]
org.springframework.context.support.AbstractApplicationContext -
Closing WebApplicationContext for namespace 'contoller-servlet':
startup date [Sun Apr 14 20:32:53 EDT 2013]; root of context hierarchy
2013-04-14 20:33:16,947 DEBUG [localhost-startStop-2]
org.springframework.beans.factory.support.AbstractBeanFactory -
Returning cached instance of singleton bean 'lifecycleProcessor'
2013-04-14 20:33:16,947 INFO [localhost-startStop-2]
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry
- Destroying singletons in
org.springframework.beans.factory.support.DefaultListableBeanFactory@2
4e
4af4d: defining beans
[springApplicationContext,/result.html,org.springframework.web.servlet
.v iew.InternalResourceViewResolver#0]; root of factory hierarchy
Linux (webapp log snippet)
...
2013-04-13 23:41:08,532 INFO [localhost-startStop-2]
org.springframework.context.support.AbstractApplicationContext -
Closing WebApplicationContext for namespace 'controller-servlet':
startup date [Sat Apr 13 23:39:28 EDT 2013]; root of context hierarchy
2013-04-13 23:41:08,535 DEBUG [localhost-startStop-2]
org.springframework.beans.factory.support.AbstractBeanFactory -
Returning cached instance of singleton bean 'lifecycleProcessor'
2013-04-13 23:41:08,536 INFO [localhost-startStop-2]
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry
- Destroying singletons in
org.springframework.beans.factory.support.DefaultListableBeanFactory@2
43
84979: defining beans
[springApplicationContext,/result.html,org.springframework.web.servlet
.v
iew.InternalResourceViewResolver#0,jdbc_rdb_127.0.0.1,jdbc_rdb_192.168
.0
.31]; root of factory hierarchy
2013-04-13 23:41:08,537 INFO [localhost-startStop-2]
com.mycompany.servlet.DSServlet - -> DSServlet|destroy()
2013-04-13 23:41:08,544 INFO [localhost-startStop-2]
com.mycompany.servlet.DSServlet - -> Releasing resources...
2013-04-13 23:41:08,545 DEBUG [localhost-startStop-2]
com.mycompany.servlet.DSServlet - -> Spring application context:
WebApplicationContext for namespace 'controller-servlet': startup date
[Sat Apr 13 23:39:28 EDT 2013]; root of context hierarchy
2013-04-13 23:41:08,546 DEBUG [localhost-startStop-2]
com.mycompany.servlet.DSServlet - -> Obtaining 'jdbc_rdb' beans of
type DSBean from the spring application context...
2013-04-13 23:41:08,577 ERROR [localhost-startStop-2]
com.mycompany.servlet.DSServlet - Unable to releaase resources.
java.lang.IllegalStateException: BeanFactory not initialized or
already closed - call 'refresh' before accessing beans via the
ApplicationContext
at
org.springframework.context.support.AbstractRefreshableApplicationCont
ex
t.getBeanFactory(AbstractRefreshableApplicationContext.java:172)
~[spring-context-3.2.0.RELEASE.jar:3.2.0.RELEASE]
at
org.springframework.context.support.AbstractApplicationContext.getBean
Na
mesForType(AbstractApplicationContext.java:1174)
~[spring-context-3.2.0.RELEASE.jar:3.2.0.RELEASE]
at com.mycompany.servlet.DSServlet.destroy(DSServlet.java:120)
~[relaism-db-0.1.0.jar:na]
at
org.apache.catalina.core.StandardWrapper.unload(StandardWrapper.java:1
48
1) [catalina.jar:7.0.39]
at
org.apache.catalina.core.StandardWrapper.stopInternal(StandardWrapper.
ja
va:1842) [catalina.jar:7.0.39]
at
org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:232)
[catalina.jar:7.0.39]
at
org.apache.catalina.core.StandardContext.stopInternal(StandardContext.
ja
va:5561) [catalina.jar:7.0.39]
at
org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:232)
[catalina.jar:7.0.39]
at
org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.ja
va
:1575) [catalina.jar:7.0.39]
at
org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.ja
va
:1564) [catalina.jar:7.0.39]
at
java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
[na:1.7.0_17]
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
[na:1.7.0_17]
at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.j
av
a:1145) [na:1.7.0_17]
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.
ja
va:615) [na:1.7.0_17]
at java.lang.Thread.run(Thread.java:722) [na:1.7.0_17]
Comparing highlighted portion clearly shows that in windows
environment,
DSSerlet.destroy() method is called, resources are cleaned, spring web
application context is closed and spring singleton beans are
destroyed.
However, as depicted in Linux log snippet, it is vice versa.
Although the webapp works perfectly fine as this problem happens when
webapp is updepolyed or tomcat is shutdown but still I cannot ignore
this because the datasources are still running and needs to be
destroyed to avoid memory leaks before undeploying webapp.
I will very much appreciate if I can get any help in finding a
solution to this problem.
Thanks in advance.
- Raza.
Do your initialization and shutdown in a ServletContextListener? They
are guaranteed to be run in the order listed in web.xml on context
startup and in the reverse order on context shutdown.
First of all thanks for replying. I am not using ServletContextListener
instead I have <servlet> defined in my web.xml as 'DSServlet' which
extends HttpServlet. So this follows a servlet life cycle which is
init(), service(), destroy() method in this sequence. I have init() and
destroy() method defined in 'DSServlet' which executes on when Servlet
is initialized and destroyed respectively. Here is my web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>dstest</display-name>
<servlet>
<servlet-name>contoller</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servle
t-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/SPRING-CONFIG/DS-CONFIG.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>dsServlet</servlet-name>
<servlet-class>com.mycompany.servlet.DSServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/SPRING-CONFIG/DS-DEFINITION-CONFIG.xml</param-valu
e>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>contoller</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
</web-app>
Another thought - is there a reason why you're not using a JNDI -
addressable connection pool?
Yes there is a reason, we have database config defined elsewhere and not
inside tomcat environment. The application reads database config and
creates data sources.
. . . just my (probably wrong) two cents.
/mde/