This is an automated email from the ASF dual-hosted git repository. jamesfredley pushed a commit to branch micronaut-fixes-2 in repository https://gitbox.apache.org/repos/asf/grails-core.git
commit 888fa45a59352b1909bd8976841497a6c497b4ed Author: James Fredley <[email protected]> AuthorDate: Thu Feb 19 00:52:40 2026 -0500 test: add integration tests for Micronaut bean type registration Add MicronautBeanTypesSpec verifying that Java @Singleton beans (via annotation processor), Groovy @Factory/@Bean beans (via AST transform), and @ConfigurationProperties beans are all correctly bridged into the Spring application context. New test bean types: - JavaSingletonService: Java class with @Singleton (annotation processor path) - FactoryCreatedService + ServiceFactory: Groovy @Factory/@Bean pattern - AppConfig: @ConfigurationProperties bound from application.yml Also adds MicronautTestController and URL mapping for manual smoke testing of bean injection across all registration mechanisms. Assisted-by: Claude Code <[email protected]> --- .../micronaut/grails-app/conf/application.yml | 2 + ...pings.groovy => MicronautTestController.groovy} | 39 +++++++--- .../controllers/micronaut/UrlMappings.groovy | 2 + .../groovy/micronaut/MicronautBeanTypesSpec.groovy | 84 ++++++++++++++++++++++ .../main/groovy/bean/injection/AppConfig.groovy} | 19 ++--- .../bean/injection/FactoryCreatedService.groovy} | 18 ++--- .../groovy/bean/injection/ServiceFactory.groovy} | 24 ++++--- .../java/bean/injection/JavaSingletonService.java | 34 +++++++++ 8 files changed, 175 insertions(+), 47 deletions(-) diff --git a/grails-test-examples/micronaut/grails-app/conf/application.yml b/grails-test-examples/micronaut/grails-app/conf/application.yml index fbf74ec5f4..82b8404555 100644 --- a/grails-test-examples/micronaut/grails-app/conf/application.yml +++ b/grails-test-examples/micronaut/grails-app/conf/application.yml @@ -48,6 +48,8 @@ spring: management: endpoints: enabled-by-default: false +app: + name: test-micronaut-app --- grails: diff --git a/grails-test-examples/micronaut/grails-app/controllers/micronaut/UrlMappings.groovy b/grails-test-examples/micronaut/grails-app/controllers/micronaut/MicronautTestController.groovy similarity index 52% copy from grails-test-examples/micronaut/grails-app/controllers/micronaut/UrlMappings.groovy copy to grails-test-examples/micronaut/grails-app/controllers/micronaut/MicronautTestController.groovy index 6751393584..ffe9a8405a 100644 --- a/grails-test-examples/micronaut/grails-app/controllers/micronaut/UrlMappings.groovy +++ b/grails-test-examples/micronaut/grails-app/controllers/micronaut/MicronautTestController.groovy @@ -16,20 +16,37 @@ * specific language governing permissions and limitations * under the License. */ - package micronaut -class UrlMappings { +import bean.injection.AppConfig +import bean.injection.FactoryCreatedService +import bean.injection.JavaSingletonService +import bean.injection.NamedService +import groovy.transform.CompileStatic + +import org.springframework.beans.factory.annotation.Autowired + +@CompileStatic +class MicronautTestController { + + @Autowired + JavaSingletonService javaSingletonService + + @Autowired + FactoryCreatedService factoryCreatedService + + @Autowired + AppConfig appConfig - static mappings = { - "/$controller/$action?/$id?(.$format)?"{ - constraints { - // apply constraints here - } - } + @Autowired + NamedService namedService - "/"(view:"/index") - "500"(view:'/error') - "404"(view:'/notFound') + def index() { + render(contentType: 'application/json', text: [ + javaMessage: javaSingletonService.message, + factoryName: factoryCreatedService.name, + appName: appConfig.name, + namedService: namedService.name + ]) } } diff --git a/grails-test-examples/micronaut/grails-app/controllers/micronaut/UrlMappings.groovy b/grails-test-examples/micronaut/grails-app/controllers/micronaut/UrlMappings.groovy index 6751393584..4e9a717ea5 100644 --- a/grails-test-examples/micronaut/grails-app/controllers/micronaut/UrlMappings.groovy +++ b/grails-test-examples/micronaut/grails-app/controllers/micronaut/UrlMappings.groovy @@ -28,6 +28,8 @@ class UrlMappings { } } + "/micronaut-test"(controller: 'micronautTest', action: 'index') + "/"(view:"/index") "500"(view:'/error') "404"(view:'/notFound') diff --git a/grails-test-examples/micronaut/src/integration-test/groovy/micronaut/MicronautBeanTypesSpec.groovy b/grails-test-examples/micronaut/src/integration-test/groovy/micronaut/MicronautBeanTypesSpec.groovy new file mode 100644 index 0000000000..25917dcf31 --- /dev/null +++ b/grails-test-examples/micronaut/src/integration-test/groovy/micronaut/MicronautBeanTypesSpec.groovy @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package micronaut + +import bean.injection.AppConfig +import bean.injection.FactoryCreatedService +import bean.injection.JavaSingletonService + +import grails.testing.mixin.integration.Integration +import org.springframework.beans.factory.annotation.Autowired +import spock.lang.Specification + +/** + * Integration tests for various Micronaut bean registration mechanisms in Grails context. + * + * Tests that: + * 1. Java @Singleton beans (processed via annotation processor) are available in Spring context + * 2. Groovy @Factory/@Bean beans (processed via AST transform) are available in Spring context + * 3. @ConfigurationProperties beans reflect Grails application.yml config into Micronaut + */ +@Integration +class MicronautBeanTypesSpec extends Specification { + + @Autowired + JavaSingletonService javaSingletonService + + @Autowired + FactoryCreatedService factoryCreatedService + + @Autowired + AppConfig appConfig + + void "Java @Singleton bean is available via Spring autowiring"() { + expect: "bean is injected and functional" + javaSingletonService != null + javaSingletonService.message == 'from-java-singleton' + } + + void "Groovy @Factory/@Bean created bean is available via Spring autowiring"() { + expect: "bean is injected with factory-configured values" + factoryCreatedService != null + factoryCreatedService.name == 'factory-created' + } + + void "@ConfigurationProperties bean reflects application.yml config"() { + expect: "config properties are bound from application.yml" + appConfig != null + appConfig.name == 'test-micronaut-app' + } + + void "Java @Singleton bean is a singleton instance"() { + when: + def first = javaSingletonService + def second = javaSingletonService + + then: "same instance is returned" + first.is(second) + } + + void "Factory-created bean is a singleton instance"() { + when: + def first = factoryCreatedService + def second = factoryCreatedService + + then: "same instance is returned (factory method annotated with @Singleton)" + first.is(second) + } +} diff --git a/grails-test-examples/micronaut/grails-app/controllers/micronaut/UrlMappings.groovy b/grails-test-examples/micronaut/src/main/groovy/bean/injection/AppConfig.groovy similarity index 73% copy from grails-test-examples/micronaut/grails-app/controllers/micronaut/UrlMappings.groovy copy to grails-test-examples/micronaut/src/main/groovy/bean/injection/AppConfig.groovy index 6751393584..1ac0201e8d 100644 --- a/grails-test-examples/micronaut/grails-app/controllers/micronaut/UrlMappings.groovy +++ b/grails-test-examples/micronaut/src/main/groovy/bean/injection/AppConfig.groovy @@ -16,20 +16,15 @@ * specific language governing permissions and limitations * under the License. */ +package bean.injection -package micronaut +import groovy.transform.CompileStatic -class UrlMappings { +import io.micronaut.context.annotation.ConfigurationProperties - static mappings = { - "/$controller/$action?/$id?(.$format)?"{ - constraints { - // apply constraints here - } - } +@ConfigurationProperties('app') +@CompileStatic +class AppConfig { - "/"(view:"/index") - "500"(view:'/error') - "404"(view:'/notFound') - } + String name } diff --git a/grails-test-examples/micronaut/grails-app/controllers/micronaut/UrlMappings.groovy b/grails-test-examples/micronaut/src/main/groovy/bean/injection/FactoryCreatedService.groovy similarity index 73% copy from grails-test-examples/micronaut/grails-app/controllers/micronaut/UrlMappings.groovy copy to grails-test-examples/micronaut/src/main/groovy/bean/injection/FactoryCreatedService.groovy index 6751393584..14d32a2b86 100644 --- a/grails-test-examples/micronaut/grails-app/controllers/micronaut/UrlMappings.groovy +++ b/grails-test-examples/micronaut/src/main/groovy/bean/injection/FactoryCreatedService.groovy @@ -16,20 +16,12 @@ * specific language governing permissions and limitations * under the License. */ +package bean.injection -package micronaut +import groovy.transform.CompileStatic -class UrlMappings { +@CompileStatic +class FactoryCreatedService { - static mappings = { - "/$controller/$action?/$id?(.$format)?"{ - constraints { - // apply constraints here - } - } - - "/"(view:"/index") - "500"(view:'/error') - "404"(view:'/notFound') - } + String name } diff --git a/grails-test-examples/micronaut/grails-app/controllers/micronaut/UrlMappings.groovy b/grails-test-examples/micronaut/src/main/groovy/bean/injection/ServiceFactory.groovy similarity index 69% copy from grails-test-examples/micronaut/grails-app/controllers/micronaut/UrlMappings.groovy copy to grails-test-examples/micronaut/src/main/groovy/bean/injection/ServiceFactory.groovy index 6751393584..c9729cdf09 100644 --- a/grails-test-examples/micronaut/grails-app/controllers/micronaut/UrlMappings.groovy +++ b/grails-test-examples/micronaut/src/main/groovy/bean/injection/ServiceFactory.groovy @@ -16,20 +16,22 @@ * specific language governing permissions and limitations * under the License. */ +package bean.injection -package micronaut +import groovy.transform.CompileStatic -class UrlMappings { +import io.micronaut.context.annotation.Bean +import io.micronaut.context.annotation.Factory - static mappings = { - "/$controller/$action?/$id?(.$format)?"{ - constraints { - // apply constraints here - } - } +import jakarta.inject.Singleton - "/"(view:"/index") - "500"(view:'/error') - "404"(view:'/notFound') +@Factory +@CompileStatic +class ServiceFactory { + + @Bean + @Singleton + FactoryCreatedService factoryCreatedService() { + new FactoryCreatedService(name: 'factory-created') } } diff --git a/grails-test-examples/micronaut/src/main/java/bean/injection/JavaSingletonService.java b/grails-test-examples/micronaut/src/main/java/bean/injection/JavaSingletonService.java new file mode 100644 index 0000000000..2dea39341d --- /dev/null +++ b/grails-test-examples/micronaut/src/main/java/bean/injection/JavaSingletonService.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package bean.injection; + +import jakarta.inject.Singleton; + +interface JavaMessageProvider { + + String getMessage(); + +} + +@Singleton +public class JavaSingletonService implements JavaMessageProvider { + + @Override + public String getMessage() { + return "from-java-singleton"; + } +}
