0

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;
    }
}

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

3 Comments

The code here is only sample. In the real product the proxy creation is done inside a factory where the class of the proxied object is not known at compilation. I was expecting something like what objenesis does, actually I don't want the super constructors to be invoked.
Oh, I did not get that Objenesis could be used together with ByteBuddy. Thanks, problem solved.
For the next version, I do actually add a constructor strategy that solves this problem as long as a constructor is side-effect free.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.