I’m new to ByteBuddy and am trying to use it to create a subclass (or redefine a class) to contain a default no args constructor in Java 17. The class currently has a constructor that accepts parameters, and it’s super class has a no args constructor.
class A {
public A() {}
}
class B {
private String field;
@Inject
public B(String field) {
this.field = field
}
}
Both classes exist in different namespaces as well (A is from another 3rd party library) i.e. com.example.namespace.A
and com.another.namespace.B
. I’ve tried to create something similar to this using ByteBuddy:
new ByteBuddy()
.subclass(B.class)
.defineConstructor(Visibility.PUBLIC)
.intercept(MethodCall
.invoke(superClass.getDeclaredConstructor())
.onSuper())
.make()
.load(B.class.getClassLoader(), ClassLoadingStrategy.Default.INJECTION)
.getLoaded();
I’ve also tried something like this:
.defineConstructor(Visibility.PUBLIC)
.withParameters((List<? extends Type>) Collections.EMPTY_LIST)
.intercept(MethodDelegation.to(new B("test") {
public void construct() throws Exception {
System.out.println("CALLING XTOR");
}
}).andThen(SuperMethodCall.INSTANCE))
In both cases I see some sort of error message like:
Caused by: java.lang.RuntimeException: java.lang.IllegalStateException: Cannot call super (or default) method for public com.another.namesapce.B()
at com.some.other.package<clinit>(DocumentationClass.java:39)
... 2 more
or
Caused by: java.lang.IllegalStateException: Cannot invoke public com.example.namespace.A() from public com.another.namespace.B() in class
To give some more details on why I’m trying to accomplish this, in case there is some other workaround, I’m passing class B as B.class
to a 3rd party library required to perform some documentation work. When I pass this without a no args constructor I receive the following error:
Caused by: java.lang.NoSuchMethodException: com.another.namespace.B$ByteBuddy$.<init>()