Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
LiuxuyangK opened this issue Jan 24, 2024 · 3 comments
Open

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

LiuxuyangK opened this issue Jan 24, 2024 · 3 comments
Assignees
Labels
Milestone

Comments

@LiuxuyangK
Copy link

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)
@raphw raphw self-assigned this Jan 28, 2024
@raphw raphw added the question label Jan 28, 2024
@raphw raphw added this to the 1.14.12 milestone Jan 28, 2024
@raphw
Copy link
Owner

raphw commented Jan 28, 2024

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.

@LiuxuyangK
Copy link
Author

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!

@raphw
Copy link
Owner

raphw commented Jan 29, 2024

Glad I could help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants