Reputation: 3667
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
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