Mix AdviceVisitor/MethodDelegation on an agent

122 views
Skip to first unread message

Philippe Bastiani

unread,
Apr 6, 2022, 5:43:39 AM4/6/22
to Byte Buddy

Hello Raphael,

I have a Java agent that instruments the code of one of my servers using Advice visitors. For a new usecase, I need to add a method to a class (note: for this UC I want to work directly on my instrumented class with no a proxy class).

First attempt (Advice visitor)

xxx.transform((builder, typeDescription, classLoader, module) -> builder
  .defineMethod("mynewmethod", MyClass.class, Visibility.PUBLIC)
  .withParameters(...)
  .intercept(Advice.to(_MyAdvice.class)));

(_MyAdvice contains a basic advice)

=> With the kind of visitor, i obtain the following error (Note: all other instrumented classes are well transformed):
[Byte Buddy] ERROR xxx [sun.misc.Launcher$AppClassLoader@18b4aac2, null, loaded=true]
java.lang.IllegalStateException: Cannot call super (or default) method for public MyClass.mynewmethod

Second attempt (MethodDelegation)

With intercept(MethodDelegation.to(_MyInterceptor.class))); and, a basic @RuntimeType interceptor.
=> With this kind of delegation, MyClass is transformed ([Byte Buddy] TRANSFORM MyClass [sun.misc.Launcher$AppClassLoader@18b4aac2, null, loaded=true]) but all other instrumented classes are not transformed

Final attempt : if i put the delegation on an existing method of MyClass; all instrumented classes are well transformed... but that's not my UC ;).

So i'm a bit confused :(
Regard,
Philippe

Rafael Winterhalter

unread,
Apr 7, 2022, 3:17:54 AM4/7/22
to Philippe Bastiani, Byte Buddy
You can likely use:

Advice.to(_MyAdvice.class).wrap(StubMethod.INSTANCE)

By default, Advice when used as an implementation mimics the visitor approach ("around") but if there is no super method to call, this would wrap the code around an empty method.

--
You received this message because you are subscribed to the Google Groups "Byte Buddy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to byte-buddy+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/byte-buddy/4ec630ae-f295-4b30-92bb-cb9c5b7fc249n%40googlegroups.com.

Philippe Bastiani

unread,
Apr 7, 2022, 7:26:39 AM4/7/22
to Byte Buddy
Thx Raphael that's solve the ERROR with the advice transformation :) But now, i enter in the dark side of the initialization ;)

Both solutions (i.e. Advice/Delegation Method) give me the same result: when I add this new instrumentation only the class(es) relating to the new advice are transformed :( And, I lose the other instrumentations defined with AdviceVisitors

As mentioned initially, if I instrument an existing method with this mechanism all my classes are properly instrumented. Therefore, I think my agent is incorrectly initialized !

I'm using this initialisation which gives me no error
new AgentBuilder.Default()
                                     // .disableClassFormatChanges()
                                     .with(new AgentBuilder.InitializationStrategy.SelfInjection.Eager())
                                     .with(AgentBuilder.RedefinitionStrategy.REDEFINITION)
                                     .with(AgentBuilder.TypeStrategy.Default.REDEFINE)

                                     .with(AgentBuilder.Listener.StreamWriting.toSystemError()
                                                                              .withErrorsOnly())
                                     .with(AgentBuilder.Listener.StreamWriting.toSystemOut()
                                                                              .withTransformationsOnly());
What is wrong ?

Rafael Winterhalter

unread,
Apr 7, 2022, 8:07:04 AM4/7/22
to Philippe Bastiani, Byte Buddy
Redefinition and self-initialization does not really work together well as static initializers are not run a second time.

Is there no log output for the classes you are missing? Are they even mentioned or do they come as IGNORED?

--
You received this message because you are subscribed to the Google Groups "Byte Buddy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to byte-buddy+...@googlegroups.com.

Philippe Bastiani

unread,
Apr 7, 2022, 12:06:51 PM4/7/22
to Byte Buddy
Yep no trace :( I'm going to synthesize my code... I need to short-circuit my code around transformations to move forward on the subject.

Rafael Winterhalter

unread,
Apr 7, 2022, 2:31:22 PM4/7/22
to Philippe Bastiani, Byte Buddy
There is no reason for it not to work from what you have shown me. If you can create a small reproducer, I could probably point you in the right direction.

Philippe Bastiani

unread,
Apr 11, 2022, 4:34:03 AM4/11/22
to Byte Buddy
Hello Rafael,


The context: the instrumented server is a Spring application.
I removed all the mechanism used to create visitors by ElementMacher.
Remains the skeleton of two Advice:
- _EsbAgentAdviced advice should detect the server startup
- _SecurityAccessAdvice should let me add a method to the SecurityAccessImpl class(Spring bean)

As previously mentioned : if I replace the method definition by a method delegation the 2 transformations are effective...

Rafael Winterhalter

unread,
Apr 11, 2022, 2:25:33 PM4/11/22
to Philippe Bastiani, Byte Buddy
Ah, you might load the type during instrumentation what automatically makes Byte Buddy skip instrumentation for this type. You can try to use AgentBuilder.Transformation.ForAdvice where you only refer to types by their name. Generally speaking, you might want to avoid loaded type symbols from your agent as this might cause class loading underways.

Philippe Bastiani

unread,
Apr 12, 2022, 3:43:33 AM4/12/22
to Byte Buddy
You pointed me in the right direction :)

Ok so, if I understand correctly, in the case of an agent, it is strongly advised to use class naming in matchers.
Thx Rafael
Reply all
Reply to author
Forward
0 new messages