-
I have a class that looks like this: public class Foo {
private String foo;
public String getFoo() {
return this.foo;
}
public void doSomething() {
String temp = this.foo;
// ...
}
} Is there any way to modify this class so that the resulting "fake" class would act like the following? //...
public void doSomething() {
String temp = this.getFoo(); // <--- replace "this.foo" by its getter
//...
} I'm already replacing the getter, but sometimes in the source code we use "direct" access to the fields, that would not give the same value than the getter. |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 8 replies
-
Yes, you are looking for MemberSubstitution. You'd replace a field read with a method invocation. |
Beta Was this translation helpful? Give feedback.
-
That's one way. You can also set Advice.OnNonDefaultValue.class and return a primitive, but I doubt it makes a performance difference. |
Beta Was this translation helpful? Give feedback.
-
I have a similar issue, but I need to replace field access inside a byte buddy Plugin implementation. @Entity
class MyEntity{
public int id;
public String name;
// getters and setters
}
class Client {
void someMethod(){
var entity = new MyEntity();
entity.id = 1; // must be replaced by entity.setId(1)
int id = entity.id; // must be replaced by entity.getId()
System.out.println("Id: " + id);
}
} My plugin class is this one: public class EntityAccessorInstrumentationPlugin implements Plugin {
@Override
public DynamicType.Builder<?> apply(
final DynamicType.Builder<?> builder,
final TypeDescription typeDescription,
final ClassFileLocator classFileLocator)
{
final Junction<FieldDescription> isInstanceField = isPublic().and(not(isStatic()));
// Intends to replace public instance fields reads by the respective getter call
final var methodWithFieldReadVisitor = MemberSubstitution.relaxed()
.field(isInstanceField)
.onRead()
.replaceWithMethod(ElementMatchers.isGetter())
.on(ElementMatchers.isMethod());
// Intends to replace public instance fields writes by the respective setter call
final var methodWithFieldWriteVisitor = MemberSubstitution.relaxed()
.field(isInstanceField)
.onWrite()
.replaceWithMethod(ElementMatchers.isSetter())
.on(ElementMatchers.isMethod());
return builder.visit(methodWithFieldReadVisitor).visit(methodWithFieldWriteVisitor);
}
} The issue is that, for instance, the methodWithFieldReadVisitor needs to find the getter matching the field that is being read and replace by the getter call, but the |
Beta Was this translation helpful? Give feedback.
-
I see, you'd need your own substitution. From it, you can investigate the intercepted element and simply delegate to the desired substitution that already ships with Byte Buddy, or implement it yourself and use some of the elements that are preshipped. |
Beta Was this translation helpful? Give feedback.
Yes, you are looking for MemberSubstitution. You'd replace a field read with a method invocation.