aboutsummaryrefslogtreecommitdiffstats
path: root/jdisc_core
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@yahooinc.com>2023-05-25 15:36:35 +0200
committerBjørn Christian Seime <bjorncs@yahooinc.com>2023-05-25 15:36:35 +0200
commit9991a10b1325f2f34a6ac833e468ff0173bb412b (patch)
tree46968044efda2f3d35742454259aa56063d608ca /jdisc_core
parentd180f4be67f0d0ea0e5dc474de4cd08b2dd71c54 (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.java17
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();