I'd like to add the following code to existing classes using ByteBuddy. Given an existing class SomeSample I want to turn this into the follwoing:
class SomeSample {
private @Transient boolean isNew = true;
public boolean isNew() {
return isNew;
}
@PrePersist
@PostLoad
void markNotNew() {
this.isNew = false;
}
}
Original attempt
I can get the field and methods added properly. What I cannot really get to work is the assignment of the value. I've learned that I need to augment all existing constructors of the class I want to augment as technically an assignment declared like this is compiled into the constructors.
I've created the following helper:
public class Helper {
@OnMethodExit
public static void initField(@FieldValue(value = "isNew", readOnly = false) boolean value) {
value = !value;
}
}
and tried to assign this as follows:
builder.constructor(ElementMatchers.any())
.intercept(Advice.to(Helper.class));
I would've expected the advice to be added at the end of the original declarations but during the build I receive the following error:
Failed to transform class files in …: Cannot call super (or default) method for public ….SomeSample()
Alternative approach
Instead of flipping the value of the field I thought I could also stay with the default (false) and negate the value returned from the generated isNew() method. If I change my helper to this:
public class Helper {
public static boolean isNew(@FieldValue(value = "isNew") boolean value) {
return !value;
}
}
When I change my method generating code for isNew() to the following:
builder = builder.defineMethod("isNew", boolean.class, Visibility.PUBLIC)
.intercept(MethodDelegation.to(Helper.class));
I get:
None of [public static boolean ….Helper.isNew(boolean)] allows for delegation from public boolean SomeSample.isNew()
Any idea?
@FieldValue(value = "isNew"), are you using theAdviceversion of the annotation here by accident?