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

I want to use bytebuddy to advice java.time.LocalDateTime

Open LiuxuyangK opened this issue 2 years ago • 3 comments

help! Looking forward to your reply! i want to advice java.time.LocalDateTime,and i use this code:

 new AgentBuilder.Default()
                .enableNativeMethodPrefix("wmsnative")
                .with(byteBuddy.with(Implementation.Context.Disabled.Factory.INSTANCE))
                .with(AgentBuilder.InitializationStrategy.NoOp.INSTANCE)
                .with(AgentBuilder.RedefinitionStrategy.REDEFINITION)
                .with(AgentBuilder.TypeStrategy.Default.REDEFINE)
                .ignore(none())
                .type(ElementMatchers.named("java.time.LocalDateTime"))
                .transform(new AgentBuilder.Transformer() {
                    @Override
                    public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader, JavaModule javaModule) {
                        return builder.method(ElementMatchers.named("now").and(ElementMatchers.takesNoArguments()))
                                .intercept(Advice.to(LocalDateTimeInterceptor.class).wrap(StubMethod.INSTANCE));
                    }
                }).installOn(install);

in the LocalDateTimeInterceptor ,the code is:

  @Advice.OnMethodExit
    public static void now(@Advice.Return(readOnly = false) LocalDateTime x) {
        Long nowSeconds = ContextThreadLocalUtil.get().getNowSeconds();
        x = TimeUtil.longSecTOLocalDateTime(nowSeconds);
    }

ContextThreadLocalUtil is a class that i write

and when i invoke LocalDateTime.now(), exception occurs:

java.lang.NoClassDefFoundError: cn/xxx/util/ContextThreadLocalUtil
        at java.time.LocalDateTime.now(LocalDateTime.java)

LiuxuyangK avatar Jan 24 '24 14:01 LiuxuyangK

LocalDateTime is on the boot loader, the class loader that is the parent of all class loaders. Your agent is however loaded on the system loader. As a result, ContextThreadLocalUtil is not visible to LocalDateTime, yielding the error you see.

Either, you need to inject the util class(es) into the boot loader (Instrumentation allows you to append to that loader) and then you need to change the module import (also via Instrumentation), or, easier, you include all your code in the advice class. The code in the advice is copied into the target method such that no visibility restrictions apply.

raphw avatar Jan 28 '24 20:01 raphw

Thank you very much for your reply. The current solution is to enhance all calls to LocalDateTime. now() in the project, which is a rather clumsy approach. However, we would like to explore the two methods you introduced in the future.

Thank you again! We are about to celebrate the Chinese New Year, which is a joyful holiday. Wishing you a happy Spring Festival!

LiuxuyangK avatar Jan 29 '24 03:01 LiuxuyangK

Glad I could help!

raphw avatar Jan 29 '24 21:01 raphw