micronaut-core
micronaut-core copied to clipboard
bug: Cannot run Groovy Script functions as a REST service since core 4.3.0
Issue description
The upgrade to core 4.3.0 seems to have broken running groovy scripts as Functions as REST services
Reproducer
Check out master of micronaut-groovy, and run:
./gradlew :micronaut-function-groovy:test --tests FunctionTransformSpec
If we switch micronaut-core back to 4.2.4 then the tests pass...
Suspicions
I suspect what is happening is the Bean definition is getting written BEFORE the AST transformation is occuring.
This means that in the class $NotifyWithArgsFunction$Definition$Reference.class with 4.3.x we get $ANNOTATION_METADATA set to
$ANNOTATION_METADATA = AnnotationMetadata.EMPTY_METADATA;
Wheras with micronaut 4.2.4, it is:
$ANNOTATION_METADATA = new DefaultAnnotationMetadata(Map.of("io.micronaut.function.FunctionBean", Map.of("method", "send", "value", "notify-with-args")), Map.of("io.micronaut.context.annotation.Executable", Map.of("processOnStartup", false), "io.micronaut.core.annotation.EntryPoint", Map.of(), "jakarta.inject.Named", Map.of("value", "notify-with-args"), "jakarta.inject.Qualifier", Map.of(), "jakarta.inject.Scope", Map.of(), "jakarta.inject.Singleton", Map.of(), "java.lang.annotation.Annotation", Map.of("name", "notify-with-args")), Map.of("io.micronaut.context.annotation.Executable", Map.of("processOnStartup", false), "io.micronaut.core.annotation.EntryPoint", Map.of(), "jakarta.inject.Named", Map.of("value", "notify-with-args"), "jakarta.inject.Qualifier", Map.of(), "jakarta.inject.Scope", Map.of(), "jakarta.inject.Singleton", Map.of(), "java.lang.annotation.Annotation", Map.of("name", "notify-with-args")), Map.of("io.micronaut.function.FunctionBean", Map.of("method", "send", "value", "notify-with-args")), Map.of("io.micronaut.context.annotation.Executable", List.of("io.micronaut.function.FunctionBean"), "io.micronaut.core.annotation.EntryPoint", List.of("io.micronaut.function.FunctionBean"), "jakarta.inject.Named", List.of("io.micronaut.function.FunctionBean"), "jakarta.inject.Qualifier", List.of("jakarta.inject.Named"), "jakarta.inject.Scope", List.of("jakarta.inject.Singleton"), "jakarta.inject.Singleton", List.of("io.micronaut.function.FunctionBean"), "java.lang.annotation.Annotation", List.of("io.micronaut.function.FunctionBean")), false, false);
Could it be that both TypeElementVisitorTransform and FunctionTransform in micronaut-groovy both use CompilePhase.SEMANTIC_ANALYSIS, and there's no guarantee of order for AST transformations in the same Phase?
I don't know much about Groovy, but you can try to find what changed vs. the version that worked.
Thanks for opening this issue @timyates. This is a blocker for four PRs I am trying to resolve for micronaut-groovy.
I don't know much about Groovy, but you can try to find what changed vs. the version that worked.
It currently makes no sense... It seems to work with core afdc5e835feff99bb9c65c2972f8b0029ec3294e
But fails with the next commit...fa244031e612d75b3994146e31e177e1ff1734e2
All that changes is the version property... I suspect something else is going on...
I don't know if transform order is the problem, but in Groovy 4+, if a transform implements TransformWithPriority, you can override the processing order of transforms within the same phase by setting a priority. They are run in order of source code appearance if in the same phase with the same priority. The transformation with the highest positive priority will be processed first. Negative priorities will be processed after all transformations with a priority of zero (the default).
I must be wrong and something else must be causing the problem...
I updated the FunctionTransform to implement TransformWithPriority and return a priority of 1, and the issue remains
Back to confused for me ;-)
@paulk-asert That is not working. I have debuged the code and the call in ASTTransformationVisitor#addPhaseOperationsForGlobalTransforms never sorts ASTTransformation