I am currently writing a maven plugin that supplies a given library with enhanced getters for all properties that carry a particular annotation as a marker.
@Reference(name="address", targetType=Address.class)
protected String addressId;
should result in a getter method with the following signature:
public Address getAddress() {
return ReferenceResolver.resolve(this, addressId, Address.class);
}
The details what the resolver is doing is basically not relevant but the method signature for the resolve()
method is the following:
public <T extends StoredObject> T resolve(StoredObject source, String key, Class<T> targetType)
Within the apply()
method of the plugin, I am looking up the fields with their names and the corresponding annotation with the expected name and type of the property getter.
builder = builder.defineMethod( "get" + name, targetType, Visibility.PUBLIC )
.intercept(MethodCall.invoke(delegate)
.withThis()
.withField(field.getName())
.with(targetType));
This does work, as long as targetType
is StoredObject.class
but as soon as targetType
is set to the expected target type Address.class
which inherits from StoredObject
, the builder bails out with the following message:
Failed to transform class maku.User: [java.lang.IllegalStateException: Cannot return T from public maku.Address maku.User.getAddress()]
The resolver is performing the necessary checks to guarantee that the returned value is assignable to the expected target type and returns the values casted to T
. However, somehow the generated code is not able to resolve the returned T
correctly as it’s bounded type StoredObject
is a superclass of the expected type and thus it is not clear if casting it would return the correct value.
I believe that I need to perform one of the following things to make it work:
- I either need to loosen the restrictions on the returned type within ByteBuddy,
- or that I need to cast the returned value myself to the expected type,
- I need to bind the generic type variable
T
to the expected type.
I have not found a way AKA some example showing how to accomplish this. Did I oversee anything or is it just not possible?
Mathias Kühn is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.