I'm trying to use bytebuddy to redefine existing classes. I'm looking for fields that are annotated with a specific annotation. I've got that figure out with code something like this:
new ByteBuddy()
.redefine(<some class>)
.field(
ElementMatchers.isAnnotatedWith(<some annotation>)
)
...
What I'd like to do is further refine my ElementMatcher to include a check for an attribute on the specified annotation - something like this:
new ByteBuddy()
.redefine(<some class>)
.field(
ElementMatchers.isAnnotatedWith(<some annotation>)
.havingAttribute(<some attribute>, "value")
)
What I'm looking for is the way to do the "havingAttribute" part. Is this possible or am I approaching this the wrong way? Any insight is appreciated.
One approach would be to create a Advice.OffsetMapping.Factory which lets you inject the annotation value in your advice like this:
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void onMethodEnter(@AnnotationValueExtractor(annotationClassName = "co.elastic.apm.api.CaptureSpan", method = "value") String spanName) {
if (spanName.equals("foo")) {
// do something special
}
}
See also: https://github.com/elastic/apm-agent-java/blob/f6781c3d740602f000332f9b4a5b5ecb0d01627a/apm-agent-core/src/main/java/co/elastic/apm/agent/bci/bytebuddy/AnnotationValueOffsetMappingFactory.java
I ended up implementing a custom ElementMatcher like this:
public class NeedsLazyToOneNoProxy<T extends AnnotationSource> extends ElementMatcher.Junction.AbstractBase<T> {
public boolean matches(T target) {
AnnotationDescription oneToOneAnnotation = target.getDeclaredAnnotations().ofType(OneToOne.class);
try {
if (oneToOneAnnotation != null) {
OneToOne oneToOne = (OneToOne) ((AnnotationDescription.Loadable) oneToOneAnnotation).load();
FetchType fetchType = oneToOne.fetch();
return fetchType == FetchType.LAZY;
}
return false;
}
catch (ClassNotFoundException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
}
I use this element matcher to determine if I should add a @LazyToOne annotation to an existing @OneToOne relationship.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With