byte-buddy icon indicating copy to clipboard operation
byte-buddy copied to clipboard

Publish blocking

Open pangdangdang opened this issue 1 year ago • 12 comments
trafficstars

<byte-buddy.version>1.14.9</byte-buddy.version>

When I enhance all classes under a package, every time I reach a subclass enhanced by cglib, no more logs are generated, and system publishing does not continue

This is one of the code segments

public class StaticApplicationContext$$EnhancerBySpringCGLIB$$2d3e27aa extends StaticApplicationContext implements EnhancedConfiguration { private boolean CGLIB$BOUND; public static Object CGLIB$FACTORY_DATA; private static final ThreadLocal CGLIB$THREAD_CALLBACKS; private static final Callback[] CGLIB$STATIC_CALLBACKS; private MethodInterceptor CGLIB$CALLBACK_0; private MethodInterceptor CGLIB$CALLBACK_1; private NoOp CGLIB$CALLBACK_2; private static Object CGLIB$CALLBACK_FILTER; private static final Method CGLIB$setBeanFactory$5$Method; private static final MethodProxy CGLIB$setBeanFactory$5$Proxy; private static final Object[] CGLIB$emptyArgs; public BeanFactory $$beanFactory;

static void CGLIB$STATICHOOK1() {
    MethodArg var10000;
    label43: {
        try {
            ProfilerAction var0 = LogActionHolder.getLogAction("profiler.agent.instrumentation.action.MethodProfilerActionImpl");
            if (Objects.nonNull(var0)) {
                var10000 = var0.onMethodEnter(new Object[0], Class.forName("com.ctrip.corp.intlflight.search.config.StaticApplicationContext$$EnhancerBySpringCGLIB$$2d3e27aa").getDeclaredMethod("CGLIB$STATICHOOK1"), false);
                break label43;
            }
        } catch (Throwable var7) {
            System.out.println("MethodServiceAdvice error" + var7);
        }

        var10000 = null;
    }

pangdangdang avatar Jun 24 '24 09:06 pangdangdang

Did you take a thread dump? Maybe you intercept a method and invoke the proxy again? Or you lock the same object from different threads.

raphw avatar Jun 25 '24 23:06 raphw

Did you take a thread dump? Maybe you intercept a method and invoke the proxy again? Or you lock the same object from different threads.

Perhaps so, I tried to configure the class that was not enhanced, and the result was successful. However, this is not safe. I tried the following code again, hoping to block the classes that have already been enhanced by cglib, but it still hasn't been blocked why? private static class InnerTransformer implements AgentBuilder.Transformer { @Override public DynamicType.Builder> transform(DynamicType.Builder> builder, TypeDescription typeDescription, ClassLoader classLoader, JavaModule module, ProtectionDomain protectionDomain) { return builder.visit(Advice.to(MethodServiceAdvice.class) .on(ElementMatchers.not(ElementMatchers.isConstructor()) .and(ElementMatchers .noneOf(ElementMatchers.hasSuperType(ElementMatchers.named("StaticApplicationContext")))) .and(ElementMatchers.not(ElementMatchers.isTypeInitializer())) .and(ElementMatchers.not(ElementMatchers.isSetter())) .and(ElementMatchers.not(ElementMatchers.isGetter())) .and(ElementMatchers.not(ElementMatchers.nameStartsWith("net.bytebuddy.generated"))) .and(ElementMatchers.not(ElementMatchers.nameContains("EnhancerBySpringCGLIB"))) .and(ElementMatchers.not(ElementMatchers.nameContains("$$"))) .and(ElementMatchers.not(ElementMatchers.nameContains("FastClassByCGLIB"))) .and(ElementMatchers.not(ElementMatchers.nameContains("MethodInterceptor"))))); } }

pangdangdang avatar Jun 27 '24 03:06 pangdangdang

take a thread dump

I tried to take a thread dump, but the PID of tomcat kept changing, so I couldn't get it

pangdangdang avatar Jun 27 '24 09:06 pangdangdang

You can use jps to find it.

raphw avatar Jun 27 '24 23:06 raphw

You can use jps to find it. I used JPS, but you can see that the displayed PID keeps changing image

pangdangdang avatar Jun 28 '24 01:06 pangdangdang

You can use jps to find it. I used JPS, but you can see that the displayed PID keeps changing

image

Can you take a look at why the filtering above doesn't work

private static class InnerTransformer implements AgentBuilder.Transformer { @OverRide public DynamicType.Builder transform(DynamicType.Builder builder, TypeDescription typeDescription, ClassLoader classLoader, JavaModule module, ProtectionDomain protectionDomain) { return builder.visit(Advice.to(MethodServiceAdvice.class) .on(ElementMatchers.not(ElementMatchers.isConstructor()) .and(ElementMatchers .noneOf(ElementMatchers.hasSuperType(ElementMatchers.named("StaticApplicationContext")))) .and(ElementMatchers.not(ElementMatchers.isTypeInitializer())) .and(ElementMatchers.not(ElementMatchers.isSetter())) .and(ElementMatchers.not(ElementMatchers.isGetter())) .and(ElementMatchers.not(ElementMatchers.nameStartsWith("net.bytebuddy.generated"))) .and(ElementMatchers.not(ElementMatchers.nameContains("EnhancerBySpringCGLIB"))) .and(ElementMatchers.not(ElementMatchers.nameContains("$$"))) .and(ElementMatchers.not(ElementMatchers.nameContains("FastClassByCGLIB"))) .and(ElementMatchers.not(ElementMatchers.nameContains("MethodInterceptor"))))); } }

pangdangdang avatar Jun 28 '24 01:06 pangdangdang

I used JPS, but you can see that the displayed PID keeps changing image

pangdangdang avatar Jun 28 '24 02:06 pangdangdang

Are those processes short lived? If so, it's hard to hit a target. Maybe you should change JAVA_TOOL_OPTIONS to add your agent when any Java process is starting up?

raphw avatar Jun 29 '24 09:06 raphw

Can you take a look at why the filtering above doesn't work

private static class InnerTransformer implements AgentBuilder.Transformer {
@OverRide
public DynamicType.Builder transform(DynamicType.Builder builder, TypeDescription typeDescription,
ClassLoader classLoader, JavaModule module, ProtectionDomain protectionDomain) {
return builder.visit(Advice.to(MethodServiceAdvice.class)
.on(ElementMatchers.not(ElementMatchers.isConstructor())
.and(ElementMatchers
.noneOf(ElementMatchers.hasSuperType(ElementMatchers.named("StaticApplicationContext"))))
.and(ElementMatchers.not(ElementMatchers.isTypeInitializer()))
.and(ElementMatchers.not(ElementMatchers.isSetter()))
.and(ElementMatchers.not(ElementMatchers.isGetter()))
.and(ElementMatchers.not(ElementMatchers.nameStartsWith("net.bytebuddy.generated")))
.and(ElementMatchers.not(ElementMatchers.nameContains("EnhancerBySpringCGLIB")))
.and(ElementMatchers.not(ElementMatchers.nameContains("$$")))
.and(ElementMatchers.not(ElementMatchers.nameContains("FastClassByCGLIB")))
.and(ElementMatchers.not(ElementMatchers.nameContains("MethodInterceptor")))));
}
}

pangdangdang avatar Jul 01 '24 03:07 pangdangdang

What filtering do you mean?

raphw avatar Jul 02 '24 20:07 raphw

What I mean is that based on the previous investigation, it seems that the classes enhanced by cglib have been enhanced again by bytebuddy. Therefore, I want to use the ElementMatchers provided by bytebuddy to filter all the classes enhanced by cglib, which is this code, but it still cannot be successfully filtered private static class InnerTransformer implements AgentBuilder.Transformer { @OverRide public DynamicType.Builder transform(DynamicType.Builder builder, TypeDescription typeDescription, ClassLoader classLoader, JavaModule module, ProtectionDomain protectionDomain) { return builder.visit(Advice.to(MethodServiceAdvice.class) .on(ElementMatchers.not(ElementMatchers.isConstructor()) .and(ElementMatchers .noneOf(ElementMatchers.hasSuperType(ElementMatchers.named("StaticApplicationContext")))) .and(ElementMatchers.not(ElementMatchers.isTypeInitializer())) .and(ElementMatchers.not(ElementMatchers.isSetter())) .and(ElementMatchers.not(ElementMatchers.isGetter())) .and(ElementMatchers.not(ElementMatchers.nameStartsWith("net.bytebuddy.generated"))) .and(ElementMatchers.not(ElementMatchers.nameContains("EnhancerBySpringCGLIB"))) .and(ElementMatchers.not(ElementMatchers.nameContains("$$"))) .and(ElementMatchers.not(ElementMatchers.nameContains("FastClassByCGLIB"))) .and(ElementMatchers.not(ElementMatchers.nameContains("MethodInterceptor"))))); } }

pangdangdang avatar Jul 03 '24 02:07 pangdangdang

You combine all these matchers. You likely want to use .or which implies that any condition holds.

raphw avatar Jul 08 '24 16:07 raphw