Allow matching annotations by name without locating annotation bytecode
Running TypePoolDefaultLazyAnnotationListTest comment out all tests besides testAnnotationIsPresent in AbstractAnnotationListTest. Add breakpoint to https://github.com/raphw/byte-buddy/blob/fbd78e1868c53b0c73b9528f821465bb3173794c/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/ClassFileLocator.java#L453 The breakpoint will hit 3 times for
net.bytebuddy.description.annotation.AbstractAnnotationListTest$Holder
net.bytebuddy.description.annotation.AbstractAnnotationListTest$Foo
net.bytebuddy.description.annotation.AbstractAnnotationListTest$Bar
Where Holder is the tested class and Foo and Bar are annotations on that class. It would be nice if it would be possible to do the match without locating Foo and Bar.
This is tricky, the annotation contract dictates that annotations with missing types are not to be rendered. So to speak, if
net.bytebuddy.description.annotation.AbstractAnnotationListTest$Foo
net.bytebuddy.description.annotation.AbstractAnnotationListTest$Bar
cannot be located, there will not be an error but the annotations would not be there. This is why the types need to be looked up.
From the api perspective it definitely makes sense to mimic what java annotation apis do and not return annotations with missing type. Though locating the bytes for the annotation class still has a non-zero cost. It would be nice if it would be possible to skip it without having to resorting to reflection to read annotationTokens from LazyTypeDescription.
If you wanted to avoid the lookup, you can create a custom TypePool where you return the annotation type without looking it up from disk. Would that be a solution? Type pools can be arranged in a hierarchy so that you can lay your own pool underneath.
I'm already using a custom TypePool so that is fine. How do I know that it is currently looking for an annotation?
That's impossible, you would need to register the names. You can however do so by maintaining a set of names that are looked up?
The look up is triggered after the check so it would be delayed until you populated the set with the name.
Alternatively, you could extend the type pool and ovverride the methods for reading annotations. The types are protected to type pool instances.
Alternatively, you could extend the type pool and ovverride the methods for reading annotations. The types are protected to type pool instances.
what do you mean by methods reading annotations, getDeclaredAnnotations in MethodDescription?
That's impossible, you would need to register the names. You can however do so by maintaining a set of names that are looked up?
You mean that I'd keep a set of annotation type names and based on that return a different result from doDescribe. How do I fill that list, how would I know which annotations current type uses?
Yes, you would have something like:
Set<String> annotations = new HashSet<>();
TypePool typePool = makePoolWithAssumedAnnotations(annotations);
annotations.add("my.Annotation");
assert typePool.describe("myType").resolve()getDeclaredAnnotations().filter(named("my.Annotation").size() == 1;
The pool would simply return a mocked up type description for an annotation type in the set if found.