diff options
author | Bjørn Christian Seime <bjorncs@yahooinc.com> | 2023-05-25 15:36:35 +0200 |
---|---|---|
committer | Bjørn Christian Seime <bjorncs@yahooinc.com> | 2023-05-25 15:36:35 +0200 |
commit | 9991a10b1325f2f34a6ac833e468ff0173bb412b (patch) | |
tree | 46968044efda2f3d35742454259aa56063d608ca /jdisc_core | |
parent | d180f4be67f0d0ea0e5dc474de4cd08b2dd71c54 (diff) |
Detect stale threads from context classloader
Diffstat (limited to 'jdisc_core')
-rw-r--r-- | jdisc_core/src/main/java/com/yahoo/jdisc/core/ContainerWatchdog.java | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/core/ContainerWatchdog.java b/jdisc_core/src/main/java/com/yahoo/jdisc/core/ContainerWatchdog.java index f28d5ea2b26..09e52beba59 100644 --- a/jdisc_core/src/main/java/com/yahoo/jdisc/core/ContainerWatchdog.java +++ b/jdisc_core/src/main/java/com/yahoo/jdisc/core/ContainerWatchdog.java @@ -160,8 +160,15 @@ class ContainerWatchdog implements ContainerWatchdogMetrics, AutoCloseable { record ThreadDetails(Thread thread, Bundle bundle) {} List<ThreadDetails> staleThreads = new ArrayList<>(); for (Thread t : threads) { + // Find threads with context classloader from an uninstalled bundle + Bundle b = isClassloaderForUninstalledBundle(t.getContextClassLoader()).orElse(null); + if (b != null) { + staleThreads.add(new ThreadDetails(t, b)); + continue; + } + // Find threads which are sub-classes of java.lang.Thread from an uninstalled bundle - Bundle b = hasClassloaderForUninstalledBundle(t).orElse(null); + b = hasClassloaderForUninstalledBundle(t).orElse(null); if (b != null) { staleThreads.add(new ThreadDetails(t, b)); continue; @@ -201,8 +208,12 @@ class ContainerWatchdog implements ContainerWatchdogMetrics, AutoCloseable { } private static Optional<Bundle> hasClassloaderForUninstalledBundle(Object o) { - if (o.getClass().getClassLoader() instanceof BundleWiringImpl.BundleClassLoader cl) { - Bundle b = cl.getBundle(); + return isClassloaderForUninstalledBundle(o.getClass().getClassLoader()); + } + + private static Optional<Bundle> isClassloaderForUninstalledBundle(ClassLoader cl) { + if (cl instanceof BundleWiringImpl.BundleClassLoader bcl) { + Bundle b = bcl.getBundle(); if (b.getState() == Bundle.UNINSTALLED) return Optional.of(b); } return Optional.empty(); |