diegomtassis
diegomtassis

Reputation: 3667

Proxy for a class with no empty constructor using ByteBuddy

Is there a way to create a proxy for a class with no empty constructor using ByteBuddy?

The idea is to create a proxy for a given concrete type and then redirect all the methods to a handler.

This test showcases the scenario of creation of a proxy for a clas with no empty constructor and it throws a java.lang.NoSuchMethodException

@Test
public void testProxyCreation_NoDefaultConstructor() throws InstantiationException, IllegalAccessException {

    // setup

    // exercise
    Class<?> dynamicType = new ByteBuddy() //
            .subclass(FooEntity.class) //
            .method(ElementMatchers.named("toString")) //
            .intercept(FixedValue.value("Hello World!")) //
            .make().load(getClass().getClassLoader()).getLoaded();

    // verify
    FooEntity newInstance = (FooEntity) dynamicType.newInstance();
    Assert.assertThat(newInstance.toString(), Matchers.is("Hello World!"));
}

The entity:

public class FooEntity {

    private String value;

    public FooEntity(String value) {
        this.value = value;
    }

    public String getValue() {
        return this.value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

Upvotes: 0

Views: 740

Answers (1)

Rafael Winterhalter
Rafael Winterhalter

Reputation: 44067

You call to subclass(FooEntity.class) implies that Byte Buddy implicitly mimics all constructors defined by the super class. You can add a custom ConstructorStrategy as a second argument to change this behavior.

However, the JVM requires that any constructor invokes a super constructor eventually where your proxied class only offers one with a single constructor. Given your code, you can create the proxy by simply providing a default argument:

FooEntity newInstance = (FooEntity) dynamicType
      .getConstuctor(String.class)
      .newInstance(null);

The field is then set to null. Alternatively, you can instantiate classes with a library like Objenesis that uses JVM internals to create instances without any constructor calls.

Upvotes: 1

Related Questions