0

I want to intercept method named methodA with one arg which's type is String as blow, what should i do. How to use hasParameters() api?

public class Demo {

    public static void main(String[] args) {

        new ByteBuddy()
                .subclass(A.class)
                .method(named("methodA").and(hasParameters(?)))
    }


    static class A {

        public void methodA() {
            System.out.println("methodA() invoked.");
        }

        public void methodA(String arg) {
            System.out.println("methodA(" + arg + ") invoked.");
        }
    }

}
Walery Strauch
  • 6,792
  • 8
  • 50
  • 57
MengZhi
  • 51
  • 5

2 Answers2

3

For this you want the ElementMatchers.takesArguments(String.class) matcher.

So something like that:

    Class<? extends A> loaded =  new ByteBuddy().subclass(A.class)
       .method(ElementMatchers.named("methodA").and(ElementMatchers.takesArguments(String.class)))
       .intercept(MethodDelegation.to(Demo.class))
       .make().load(Demo.class.getClassLoader(), ClassLoadingStrategy.Default.INJECTION).getLoaded();

    A instance = loaded.getConstructor().newInstance();
    instance.methodA("abc");
    instance.methodA();


public class Demo {

    static void intercept(String arg){
         System.out.println("intercepted");
    }
}
k5_
  • 5,450
  • 2
  • 19
  • 27
  • Thank you very much. I use ElementMatchers.hasParameters method and implement ElementMatcher> interface to achieve my purpose finally, and it work well. – MengZhi Sep 05 '17 at 02:26
0

To clarify, you need to define a matcher (similar to a filter) to apply to methods. Create some constraint in the matcher so it will only match to some parameter structure you specify:

ElementMatcher<Iterable<? extends ParameterDescription>> matcher = parameterDescriptions -> {
    for (ParameterDescription p : parameterDescriptions) {
        if (p.getType().equals(TypeDescription.STRING.asGenericType()) && p.getIndex() == 0) return true;
    }
    return false;
};

ByteBuddyAgent.install();
new ByteBuddy()
    .redefine(SomeType.class)
    .method(ElementMatchers.hasParameters(matcher))
    .intercept(FixedValue.value("Hello World"))
    .make()
    .load(SomeType.class.getClassLoader(), 
        ClassReloadingStrategy.fromInstalledAgent());
ryan
  • 5
  • 3