micronaut-projects / micronaut-core

Micronaut Application Framework
http://micronaut.io
Apache License 2.0
6.01k stars 1.04k forks source link

bug: Cannot run Groovy Script functions as a REST service since core 4.3.0 #10580

Open timyates opened 4 months ago

timyates commented 4 months ago

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

The 4 REST tests will fail

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);
timyates commented 4 months ago

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?

dstepanov commented 4 months ago

I don't know much about Groovy, but you can try to find what changed vs. the version that worked.

wetted commented 4 months ago

Thanks for opening this issue @timyates. This is a blocker for four PRs I am trying to resolve for micronaut-groovy.

timyates commented 4 months ago

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...

paulk-asert commented 3 months ago

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).

timyates commented 3 months ago

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 ;-)