diff --git a/common/src/main/java/io/netty/util/ThreadDeathWatcher.java b/common/src/main/java/io/netty/util/ThreadDeathWatcher.java index 578ce76169..6d487533c9 100644 --- a/common/src/main/java/io/netty/util/ThreadDeathWatcher.java +++ b/common/src/main/java/io/netty/util/ThreadDeathWatcher.java @@ -104,6 +104,13 @@ public final class ThreadDeathWatcher { if (started.compareAndSet(false, true)) { Thread watcherThread = threadFactory.newThread(watcher); + // Set to null to ensure we not create classloader leaks by holds a strong reference to the inherited + // classloader. + // See: + // - https://github.com/netty/netty/issues/7290 + // - https://bugs.openjdk.java.net/browse/JDK-7008595 + watcherThread.setContextClassLoader(null); + watcherThread.start(); ThreadDeathWatcher.watcherThread = watcherThread; } diff --git a/common/src/main/java/io/netty/util/concurrent/GlobalEventExecutor.java b/common/src/main/java/io/netty/util/concurrent/GlobalEventExecutor.java index e1f7679e5a..b6e9eba579 100644 --- a/common/src/main/java/io/netty/util/concurrent/GlobalEventExecutor.java +++ b/common/src/main/java/io/netty/util/concurrent/GlobalEventExecutor.java @@ -215,6 +215,13 @@ public final class GlobalEventExecutor extends AbstractScheduledEventExecutor { private void startThread() { if (started.compareAndSet(false, true)) { Thread t = threadFactory.newThread(taskRunner); + // Set to null to ensure we not create classloader leaks by holds a strong reference to the inherited + // classloader. + // See: + // - https://github.com/netty/netty/issues/7290 + // - https://bugs.openjdk.java.net/browse/JDK-7008595 + t.setContextClassLoader(null); + // Set the thread before starting it as otherwise inEventLoop() may return false and so produce // an assert error. // See https://github.com/netty/netty/issues/4357