Thank you Jochen I further narrowed this down to this behaviour
- I have an annotation MyAnnotation. This is marked as SOURCE retention and is used as a repeatable annoation - I have another annotation MyGroupAnnotation. This is marked as RUNTIME retention - I have an AST transformation that removes all MyAnnotation on the type it is defined on and collates them into MyGroupAnnotation @MustBeDocumented @Retention(AnnotationRetention.SOURCE) @Target(AnnotationTarget.FUNCTION) annotation class MyAnnotation(...) @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) @Target(AnnotationTarget.FUNCTION) annotation class MyGroupAnnotation( val all: Array<RemoteActivity> = [] ) This is how I use it @MyAnnotation(...) @MyAnnotation(...) List<MyStuff> someMethod(List<MyStuff> blah) And this is how it ends up after the AST @MyGroupAnnotation(all = [MyAnnotation(...), MyAnnotation(...)]) List<MyStuff> someMethod(List<MyStuff> blah) When I use someMethod, if it has already been loaded separately by the same class loader, the MethodNode representing someMethod contains 1 annotation (MyGroupAnnotation) with 1 member which is a list but that list has one NULL value in it This seems to be because it goes through Java8::annotationValueToExpression(...) through the array section and then back into annotationValueToExpression where it sees an instance of a proxy object instead of a Class definition. So it returns NULL Not sure if this rings any bells, I am lost though. This seems to work if I load someMethod from a jar or class path. This only fails if I use the same class loader that compiled someMethod regards Saravanan On Fri, Mar 4, 2022 at 5:44 PM Jochen Theodorou <blackd...@gmx.org> wrote: > On 15.02.22 05:20, Saravanan Palanichamy wrote: > > Hello Groovy users > > > > I am using Groovy 3.0.5 > > > > * I have a file A.groovy and B.groovy. B depends on A > > * I have ast transformations that add annotations to methods in A > > (specifically an annotation with a list expression that contains > > other annotations) > > * I compile A.groovy using the loadClass and then compile B.groovy > > again with load class. When I inspect a method call to A(using the > > method target field inside method call expression), I see only null > > values for the annotations I added > > * If I compiled B.groovy and have it automatically detect A.groovy, I > > see the right values for my annotations (no nulls) > > > > Any idea why this is happening? > > If the annotations are directly in the file, then the one way this makes > sense to me is that you load a different A. That would mean your class > loader you use for B finds a different A, then the one you loaded (given > you loaded the right A of course). Without further details about the > setup this is a bit difficult. I suggest you do the following style of > test: > > * loadClass for A, and keep a reference to A: x=loadClass("A") > * have B return the class A (something like "return A.class") > * loadClass for B and execute the code that returns A: > y=loadClass("B").getA() > * now the first A and the second A must be fulfilling referential > identity: assert x===y > > If the assert fails it is clear that you are doing something wrong with > your class loaders. If the assert does not fail I suggest to stop after > loading A and checking that the annotations are on it. If they are not, > you load the wrong A - wherever A is coming from. If they are there, but > later not... well then you created some very very strange case that > violates classloader constraints, because that means A has been modified > after the class has been loaded, without loading a new A. Not sure you > can do that even with instrumentation to that extend. > > bye Jochen > >