Skip to content

SpringBootExceptionHandler thread local leak reported by Tomcat #40206

@stefanodelfalk

Description

@stefanodelfalk

To reproduce (this was on Java 17.0.10, Tomcat 10.1.19, Spring Boot 3.2.4):

  1. Define any spring.main property (e.g. spring.main.banner_mode=off).
  2. Deploy your application as a WAR file in Tomcat.
  3. Start Tomcat, then exit with ctrl-c.
  • On startup, from SpringApplication.bindToSpringApplication, the JavaBeanBinder for "spring.main" finds the property defined in hasKnownBindableProperties and does not skip binding.
  • When it gets to the "spring.main.spring-boot-exception-handler" property, it has found the get method SpringApplication.getSpringBootExceptionHandler but not yet invoked it.
  • Because we're running in Tomcat, we have the JndiPropertySource, so the test containsNoDescendantOf in Binder.bindObject returns false, causing the property to be bound.
  • Finally, there was a change in DefaultBindConstructorProvider somewhere between 2.7.18 and 3.0.13 so it now not only calls bindable.getValue() but also bindable.getValue().get(). This invokes getSpringBootExceptionHandler (on the main thread) so the ThreadLocal is always created.

Tomcat's WebappClassLoaderBase.checkThreadLocalsForLeaks will log this as a severe problem when you stop the web application.

I can't really see a good way around this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions