Search code examples
javabyte-buddy

Redefine methods with ByteBuddy


I am trying to redefine some methods using ByteBuddy. when I intercept methods with FixedValue.value(), it's fine. but intercept methods with an interceptor, the compiler throws UnsupportedOperationException.

I want to override the "Foo.nothing()" method to print something.

public class Foo {
    public String getHello() {
        return "not redefined hello!";
    }
    public String getBye() {
        return "not redefined Bye!";
    }
    public void nothing() {}
}

here is my interceptor:

public class GeneralInterceptor {
    @RuntimeType
    public Object intercept(@AllArguments Object[] allArguments,
                            @Origin Method method) {
        System.out.println("asdfasdf");
        return null;
    }
}

and here is my redefining code

public class RedefineTest {
    ClassReloadingStrategy classReloadingStrategy;
    @BeforeEach
    public void init() {
        ByteBuddyAgent.install();
        classReloadingStrategy = ClassReloadingStrategy.fromInstalledAgent();
    }

    @Test
    public void redefineTest() {
        // okay
        new ByteBuddy()
                .redefine(Foo.class)
                .method(named("getHello"))
                .intercept(FixedValue.value("ByteBuddy Hello!"))
                .make()
                .load(Foo.class.getClassLoader(), classReloadingStrategy);
        // error
        new ByteBuddy()
                .redefine(Foo.class)
                .method(named("nothing"))
                .intercept(MethodDelegation.to(new GeneralInterceptor()))
                .make()
                .load(Foo.class.getClassLoader(), classReloadingStrategy);
        Foo foo = new Foo();
        System.out.println(foo.getHello());
        System.out.println(foo.getBye());
        foo.nothing();
    }
}

Solution

  • I solved!

    public class GeneralInterceptor {
        @RuntimeType
        public static Object intercept(@AllArguments Object[] allArguments) {
            System.out.println("asdfasdf");
            return null;
        }
    }
    

    and change

    intercept(MethodDelegation.to(new GeneralInterceptor())

    to

    intercept(MethodDelegation.to(GeneralInterceptor.class)