Skip to content

Fix ClassLoader leak caused by static ExecutorService in Async#2255

Open
Dev10-sys wants to merge 1 commit intoLFDT-web3j:mainfrom
Dev10-sys:fix/async-executor-memory-leak
Open

Fix ClassLoader leak caused by static ExecutorService in Async#2255
Dev10-sys wants to merge 1 commit intoLFDT-web3j:mainfrom
Dev10-sys:fix/async-executor-memory-leak

Conversation

@Dev10-sys
Copy link
Copy Markdown
Contributor

@Dev10-sys Dev10-sys commented Apr 3, 2026

What does this PR do?

This PR adds a manual shutdown method for the static ExecutorService used in Async.java.

Right now the executor is only shut down using a JVM shutdown hook. This works for
normal applications, but in web containers like Tomcat or Jetty the JVM does not stop
when a web application is reloaded or undeployed. Because of this, the executor threads
can stay alive and keep references to the old ClassLoader, which may cause memory leaks
over time.

This change adds a public static shutdown() method so the executor can be stopped
manually when the application is being shut down or undeployed.

The shutdown method safely:

  • Calls shutdown()
  • Waits for termination
  • Calls shutdownNow() if needed
  • Handles InterruptedException
  • Can be called multiple times safely

This change does not modify existing behavior and is backward compatible.

Why is it needed?

In web container environments, applications can be reloaded without stopping the JVM.
In that case, the static executor may keep running and hold references to the old
ClassLoader, which can lead to ClassLoader memory leaks. Providing a manual shutdown
method allows proper cleanup.

Checklist

  • I've read the contribution guidelines
  • I've added tests (not applicable for this small fix)
  • I've added a changelog entry if required

Fixes #2244

@gtebrean
Copy link
Copy Markdown
Contributor

over all this is:

Also:

  • DCO is failing
  • there is no changelog.md update

@Dev10-sys Dev10-sys force-pushed the fix/async-executor-memory-leak branch 4 times, most recently from 1abc937 to 68a6e16 Compare April 22, 2026 09:23
- Improve Async executor handling to prevent memory leaks in web containers.
- Implement thread-safe lazy initialization of the executor.
- Allow safe re-initialization of the executor after it has been shut down.
- Add thread naming and daemon status to the shared thread pool for better visibility.
- Include AsyncLifecycleTest to verify the fix.
- Fixes LFDT-web3j#2244

Signed-off-by: Dev10-sys <kalpanagola9897@gmail.com>
@Dev10-sys Dev10-sys force-pushed the fix/async-executor-memory-leak branch from 68a6e16 to 8315323 Compare April 22, 2026 09:26
@Dev10-sys
Copy link
Copy Markdown
Contributor Author

@gtebrean Thanks for feedback, that helped.
I have updated the implementation to support lazy reinitialization so the executor can safely be recreated after shutdown, which should handle container lifecycle cases better.
Also added a lifecycle test to verify shutdown and reuse, fixed the DCO issue and updated the changelog.
Everything is passing locally and CI is green now.

Let me know if there’s anything else you’d like me to adjust.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Static ExecutorService in Async.java causes ClassLoader leaks in Web Containers

2 participants