byte-buddy
byte-buddy copied to clipboard
`MemberAttributeExtension.ForField().on(…)` does not consider previously added annotations
Assume I have some code that adds an annotation to a field using:
new MemberAttributeExtension.ForField()
.annotate(…);
and a second declaration (in another ByteBuddy plugin) that would attempt the same, but guards against the presence of the potentially previously added annotation:
new MemberAttributeExtension.ForField()
.annotate(…)
.on(…) // Receiving a filter for the annotation to be added
The condition handed into ….on(…) seems to only consider the annotations originally present on the type. I essentially need to write code that adds the annotation once as the individual invocations to add it don't know about each other. Alternatively, I wonder if the addition of an annotation could be deduplicated for identical AnnotationDeclarations as otherwise invalid annotation declarations are produced.
Unfortunately, the internal model is not currently strong enough to capture "on the fly changes" made by ASM visitors. Your best option right now would be to add a custom visitor that strips annotations by a given criteria and then write your own annotation after visiting everything that was added previously.
In order to avoid this, you can transform a type, write it to a byte array and then read it and reprocess it, but that is rather costly.
I seem to run into this problem even with a single plugin declaring the annotation within Eclipse. I wonder whether this is related to m2e likely keeping the build plugin instance around. In that case, I think the class files are read once into TypeDescriptors, transformation logic is applied and the class files rewritten. A subsequent invocation of the plugin (the same instance) would then not re-read the TypeDescriptors, would it? Thus, the matching logic would still not see the guards and perform the annotation addition a second time?
Is there a way to tweak the ClassFileLocator so that it re-initializes for all invocations of the plugin instance?
This might be the cache that is used? Can you try to use a PoolStrategy that uses a no-op cache?