raphw / byte-buddy

Runtime code generation for the Java virtual machine.
https://bytebuddy.net
Apache License 2.0
6.23k stars 804 forks source link

matched class wasn't transformered and the issue appears just twice, and i didn't reproducing the issue #1600

Closed fuckeversec closed 6 days ago

fuckeversec commented 7 months ago

jdk version is jdk-1.8.0_60s, and bytebuddy version is 1.10.22

the transformer code as belong:

@Override
public Builder<?> transform(Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader,
        JavaModule module) {

    if (isInterface().matches(typeDescription) || isEnum().matches(typeDescription)) {
        return builder;
    }

    List<InDefinedShape> needDesensitizeFields = typeDescription.getDeclaredFields()
        .filter(fieldDescriptionJunction);

    if (CollectionUtils.isEmpty(needDesensitizeFields)) {
        return builder;
    }

    log.info("class {} rebased", typeDescription.getTypeName());
    DESENSITIZATION_CLASSES.add(typeDescription.getTypeName());

    return builder.method(named("toString"))
        .intercept(MethodDelegation.to(LogAdvice.class))
        .field(isAnnotatedWith(Desensitization.class).and(
            ElementMatchers.not(ElementMatchers.isAnnotatedWith(JsonSerialize.class))))
        .annotateField(jacksonSerializeAnno);
}

there are two class A and B, they are all matched for this transformer, but the problem is just class B was transformered and class A was skipped, i use same jdk and same application jar, restart application 30000 times to reproducing the issue, but the problem was't occur. I use net.bytebuddy.agent.ByteBuddyAgent.install method to instrumentation at runtime, doesn't use jvm agent method.

raphw commented 7 months ago

Are you retransforming? If so, a class might be loaded when matching it. What does the log say? Does the missing class show up at all?

fuckeversec commented 7 months ago

I didn't retransforming the class.

the matcher code is belong, use nameStartsWith to filter class.

agentBuilder.type(nameStartsWith("com.pay"))
                .transform(new JacksonFieldDesensitizingTransformer())

SendCashReq class has a field recvBankCardNum annotate with Desensitization:

@Desensitization("BANKCARD_MASK")
private String recvBankCardNum;

the issue case log is: INFO: 2024-02-01 17:33:47.267 [main] JacksonFieldDesensitizingTransformer - [logid:] [clientip:] [localip:] class com.pay.epic.api.model.vo.ActivityBankCardInfoVo rebased

the correct case log is: INFO: 2024-02-01 22:24:10.984 [main] JacksonFieldDesensitizingTransformer - [logid:] [clientip:] [localip:] class com.pay.epic.service.client.req.SendCashReq rebased INFO: 2024-02-01 22:24:11.473 [main] JacksonFieldDesensitizingTransformer - [logid:] [clientip:] [localip:] class com.pay.epic.api.model.vo.ActivityBankCardInfoVo rebased

Like the above log shows, the application has two class matched the matcher's rule. SendCashReq class wasn't rebased, That case was occered twice.

raphw commented 7 months ago

To me it seems as if SendCashReq is already loaded in that case. Are you logging ignored classes? Any class passed to Byte Buddy would get logged here.

fuckeversec commented 7 months ago

I think the class was already loaded too. I didn't log this message. I restart the application and use jvm option to logging loaded class. The SendCashReq class was at very later. What kind of case that make the SendCashReq was loadded at the beginning even before the main class. I install bytebuddy instrument at the main method first line.

raphw commented 7 months ago

Do you reference losded classes somewhere? Byte Buddy would not load it itself. Are you running premain? In this case the app should not even come up before installing the sgent.

fuckeversec commented 7 months ago

I use net.bytebuddy.agent.ByteBuddyAgent.install(), not running premain. But the install method is at first line in main method. I didn't reference SendCashReq on main classs.

raphw commented 7 months ago

That's strange then. I'd activate logging of class loading on the JVM level and see if I can stitch it together based on that.

fuckeversec commented 7 months ago

Hello, have you reproduced this issue? Have you identified the root cause of the problem?

raphw commented 7 months ago

No, I have no opportunity to reproduce this problem. Did you try logging of class loading?

fuckeversec commented 7 months ago

I logging of class loading when restart the application in test enviroment, but the error doesn't occur.