Background: I want to instrument all implementations of a set of interfaces (within the same package) with a LogInterceptor (just logging that the method was called). Therefore I wrote a javaagent with byte-buddy. In general that is working fine, but I'm struggling with finding all implementations of a set of interfaces.
Assume we have a set of Java interfaces in a package my.company.api, then I tried it the following way:
public static void premain(String arguments, Instrumentation instrumentation) {
new AgentBuilder.Default()
.ignore(ElementMatchers.isInterface())
.ignore(ElementMatchers.isEnum())
.type(ElementMatchers.nameMatches("my\\.company\\.api\\..*"))
.transform(new AgentBuilder.Transformer() {
@Override
public DynamicType.Builder transform(DynamicType.Builder builder, TypeDescription typeDescription, ClassLoader classloader) {
return builder
.method(ElementMatchers.isPublic())
.intercept(MethodDelegation.to(LogInterceptor.class));
}
}).installOn(instrumentation);
}
I am quite new with byte-buddy, maybe someone can give me a hint what I am doing wrong.
First of all, you are not chaining the ignore matchers correctly; it should be:
.ignore(isInterface().or(isEnum()))
As for matching the interfaces, you can try the hasSuperType
matcher. If you try to match interfaces of a given package, you might try:
hasSuperType(nameStartsWith("my.company.api.").and(isInterface()))
Using a prefix matcher is much more efficient compared to a regex.