chschroe
chschroe

Reputation: 179

Can I redefine private methods using Byte Buddy?

Is it possible to use Byte Buddy to redefine a private method of a class? It seems that the entry point into using Byte Buddy is always sub-classing an existing class. When doing this, it is obviously not possible to redefine a private method of the parent class (at least not in a way that the redefined method is used in the parent class).

Consider the following example:

public class Foo {
    public void sayHello() {
        System.out.println(getHello());
    }

    private String getHello() {
        return "Hello World!";
    }
}

Foo foo = new ByteBuddy()
    .subclass(Foo.class)
    .method(named("getHello")).intercept(FixedValue.value("Byte Buddy!"))
    .make()
    .load(Main.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
    .getLoaded()
    .newInstance();
foo.sayHello();

The output will be "Hello World!". Is there any chance to get "Byte Buddy!" as output?

Upvotes: 3

Views: 3593

Answers (1)

Rafael Winterhalter
Rafael Winterhalter

Reputation: 44032

You are correct that subclassing is the currently only option for creating classes with Byte Buddy. However, starting with version 0.3 which is released in the next weeks, this will change such that you can also redefine existing classes. A class redefition would then look like this:

ClassReloadingStrategy classReloadingStrategy = ClassReloadingStrategy
                                                   .fromInstalledAgent();
new ByteBuddy()
  .redefine(Foo.class)
  .method(named("getHello"))
  .intercept(FixedValue.value("Byte Buddy!"))
  .make()
  .load(Foo.class.getClassLoader(), classReloadingStrategy);
assertThat(foo.getHello(), is("Byte Buddy!"));
classReloadingStrategy.reset(Foo.class);
assertThat(foo.getHello(), is("Hello World"));

This approach makes use of HotSpot's HotSwap mechanism which is very limited as you cannot add methods or fields. With Byte Buddy version 0.4, Byte Buddy will be able to redefine unloaded classes and provide an agent builder for implementing custom Java Agents to make this sort of redefinition more flexible.

Upvotes: 3

Related Questions