Why Spring Context not gracefully closed?
Asked Answered
F

1

10

On stop or undeploy/redeploy of a Spring framework 3.0.5 based web application following error is logged in Tomcat7's catalina.out:

SEVERE: The web application [/nomination##1.0-qa] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@4f43af8f]) and a value of type [org.springframework.security.core.context.SecurityContextImpl] (value [org.springframework.security.core.context.SecurityContextImpl@ffffffff: Null authentication]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.

I initially thought of implementing ServletContextListener and close() the context there. However, found ContextLoaderListener which implements ServletContextListener is set up like so in web.xml:

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

From Javadocs:

**contextDestroyed**

public void contextDestroyed(ServletContextEvent event)
Close the root web application context.
Specified by:
contextDestroyed in interface ServletContextListener

So, my question is why the ThreadLocal not cleanly freed by ContextLoaderListener.contextDestroyed()?

We are running into PermGen errors and while investigating found this. There is code similar to the following in a few places:

ApplicationContext context = WebApplicationContextUtils
            .getWebApplicationContext(se.getSession().getServletContext());

MyBeanClass x = context.getBean(
            "myBean", MyBeanClass.class);
x.someMethod(); 

I wonder if the above snippet is stopping a clean shutdown? Any pointers will be greatly appreciated.

Freiburg answered 9/5, 2013 at 14:38 Comment(5)
I started having this error when breaking my root application context into two. Instead of a single root context with two child servlet contexts, I now have a root context for bootstrap (with the same two child servlet contexts) and I programmatically create a child context later on. The security configuration continues to stay in the root application context in this design, but the leak warnings have appeared now. Clearly this is related in my case to the splitting of the root application context in two.Blotto
@Mihai Danila I only have a single application context.Freiburg
How is your security context setup ?Enenstein
Did you de registered drivers ? @Override public void contextDestroyed(ServletContextEvent arg0) { Enumeration<Driver> drivers = DriverManager.getDrivers(); while (drivers.hasMoreElements()) { Driver driver = drivers.nextElement(); try { DriverManager.deregisterDriver(driver); } catch (SQLException e) { } } }Gimp
@MihaiDanila I know it's a bit late, but can you please share your app ctx? Thanks.Freiburg
G
0

There is many issues by hotdeploy that you should care:

1-Deregister Database drivers see here.

2-Close tasks in multi tasking apps:you may place delay of restart in development mode almost 1 hour.

3-Kill context of spring :you did above but pay attention don't import XML form XML .

4-Kill cached objects that exist in JVM memory :make small object, are you initializing bean in constructor? change it to to none constructor to keep kill them in method scope! how many method in class calling bean? if many method calls bean don't expect java kill object after come out from scope ,jvm will keep it for performance..,so keep your class small!.

How is your code? are you declare variable out of loops? Are you =null list or object after usage?

5- you may increase tomcat start time and stop time.

also see rebel or springboot projects as helper .

Gimp answered 13/6, 2014 at 8:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.