Skip to content

Missing bean class in native image with a Kotlin nested class #32472

@juliuskrah

Description

@juliuskrah

Affects: <6.1.2>
Reproducer: https://github.com/juliuskrah/graphql-demo/tree/spf-32472

Missing class in AOT processed Bean

Given the following bean definition:

class MongockBeanDefinitionRegistrar(
    private val environment: Environment
): ImportBeanDefinitionRegistrar {
// ...

    override fun registerBeanDefinitions(
        metadata: AnnotationMetadata,
        registry: BeanDefinitionRegistry,
        importBeanNameGenerator: BeanNameGenerator,
    ) {
      // ...
       val mongockSupportBeanDefinitionBuilder = BeanDefinitionBuilder
            .rootBeanDefinition(MongockRunnerSupport::class.java)
            .addPropertyValue("migrationClasses", changeUnitSets)
            .addPropertyReference("driver", "connectionDriver")
            .addPropertyReference("config", "mongock-io.mongock.runner.springboot.base.config.MongockSpringConfiguration")

        val mongockRunnerBeanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(MongockRunner::class.java)
            .setFactoryMethodOnBean("create", "mongockRunnerSupport")
            .setInitMethodName("execute")

        registry.registerBeanDefinition(getName(MongockRunner::class.java), mongockRunnerBeanDefinitionBuilder.beanDefinition)
        registry.registerBeanDefinition("mongockRunnerSupport", mongockSupportBeanDefinitionBuilder.beanDefinition)
  }

  class MongockRunnerSupport: ApplicationContextAware, ApplicationEventPublisherAware {
        var driver: ConnectionDriver? = null
        var config: MongockConfiguration? = null
        var migrationClasses: List<Class<*>>? = emptyList()
        private lateinit var applicationContext: ApplicationContext
        private lateinit var eventPublisher: ApplicationEventPublisher

        fun create(): MongockRunner {
            val builder: RunnerSpringbootBuilder = MongockSpringboot.builder()
            if (this.driver != null) builder.setDriver(driver)
            if (this.config != null) builder.setConfig(config)
            builder.setSpringContext(applicationContext)
            builder.setEventPublisher(eventPublisher)
            migrationClasses?.forEach(builder::addMigrationClass)
            return builder.buildRunner()
        }

        override fun setApplicationContext(applicationContext: ApplicationContext) {
            this.applicationContext = applicationContext
        }

        override fun setApplicationEventPublisher(applicationEventPublisher: ApplicationEventPublisher) {
            this.eventPublisher = applicationEventPublisher
        }
    }
}

The aot process generates the following class:

@Generated
public class MongockBeanDefinitionRegistrar__BeanDefinitions {

  @Generated
  public static class MongockRunnerSupport {

    private static BeanInstanceSupplier<MongockRunner> getMongockRunnerInstanceSupplier() {
      return BeanInstanceSupplier.<MongockRunner>forFactoryMethod(MongockBeanDefinitionRegistrar.MongockRunnerSupport.class, "create")
              .withGenerator((registeredBean) -> registeredBean.getBeanFactory().getBean(MongockBeanDefinitionRegistrar.MongockRunnerSupport.class).create());
    }


    public static BeanDefinition getMongockRunnerBeanDefinition() {
      RootBeanDefinition beanDefinition = new RootBeanDefinition(MongockRunner.class);
      beanDefinition.setTargetType(MongockRunner.class);
      beanDefinition.setInitMethodNames("execute");
      beanDefinition.setInstanceSupplier(getMongockRunnerInstanceSupplier());
      return beanDefinition;
    }


    public static BeanDefinition getMongockRunnerSupportBeanDefinition() {
      RootBeanDefinition beanDefinition = new RootBeanDefinition(MongockBeanDefinitionRegistrar.MongockRunnerSupport.class);
      beanDefinition.getPropertyValues().addPropertyValue("migrationClasses", List.of(CreateProductCollectionChangeUnit202401151530.class));
      beanDefinition.getPropertyValues().addPropertyValue("driver", new RuntimeBeanReference("connectionDriver"));
      beanDefinition.getPropertyValues().addPropertyValue("config", new RuntimeBeanReference("mongock-io.mongock.runner.springboot.base.config.MongockSpringConfiguration"));
      beanDefinition.setInstanceSupplier(MongockBeanDefinitionRegistrar.MongockRunnerSupport::new);
      return beanDefinition;
    }
  }
}

I encounter the following exception when running the native executable:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongockRunnerSupport': Unresolved class: class com.example.graph.spring.MongockBeanDefinitionRegistrar$MongockRunnerSupport (kind = CLASS)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:606) ~[graphql-demo:6.1.2]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[graphql-demo:6.1.2]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) ~[graphql-demo:6.1.2]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[graphql-demo:6.1.2]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) ~[graphql-demo:6.1.2]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:224) ~[graphql-demo:6.1.2]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1323) ~[graphql-demo:6.1.2]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1284) ~[graphql-demo:6.1.2]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveBean(DefaultListableBeanFactory.java:486) ~[graphql-demo:6.1.2]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:341) ~[graphql-demo:6.1.2]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:334) ~[graphql-demo:6.1.2]
	at com.example.graph.spring.MongockBeanDefinitionRegistrar__BeanDefinitions$MongockRunnerSupport.lambda$getRunnerSpringbootBuilderInstanceSupplier$0(MongockBeanDefinitionRegistrar__BeanDefinitions.java:28) ~[na:na]
	at org.springframework.util.function.ThrowingFunction.apply(ThrowingFunction.java:63) ~[graphql-demo:6.1.2]
	at org.springframework.util.function.ThrowingFunction.apply(ThrowingFunction.java:51) ~[graphql-demo:6.1.2]
	at org.springframework.beans.factory.aot.BeanInstanceSupplier.lambda$withGenerator$0(BeanInstanceSupplier.java:171) ~[na:na]
	at org.springframework.util.function.ThrowingBiFunction.apply(ThrowingBiFunction.java:68) ~[graphql-demo:6.1.2]
	at org.springframework.util.function.ThrowingBiFunction.apply(ThrowingBiFunction.java:54) ~[graphql-demo:6.1.2]
	at org.springframework.beans.factory.aot.BeanInstanceSupplier.lambda$get$2(BeanInstanceSupplier.java:206) ~[na:na]
	at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58) ~[graphql-demo:6.1.2]
	at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46) ~[graphql-demo:6.1.2]
	at org.springframework.beans.factory.aot.BeanInstanceSupplier.invokeBeanSupplier(BeanInstanceSupplier.java:218) ~[na:na]
	at org.springframework.beans.factory.aot.BeanInstanceSupplier.get(BeanInstanceSupplier.java:206) ~[na:na]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.obtainInstanceFromSupplier(DefaultListableBeanFactory.java:949) ~[graphql-demo:6.1.2]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1216) ~[graphql-demo:6.1.2]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1160) ~[graphql-demo:6.1.2]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:561) ~[graphql-demo:6.1.2]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[graphql-demo:6.1.2]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) ~[graphql-demo:6.1.2]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[graphql-demo:6.1.2]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) ~[graphql-demo:6.1.2]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[graphql-demo:6.1.2]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975) ~[graphql-demo:6.1.2]
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:960) ~[graphql-demo:6.1.2]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:625) ~[graphql-demo:6.1.2]
	at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:66) ~[graphql-demo:3.2.1]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:762) ~[graphql-demo:3.2.1]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:464) ~[graphql-demo:3.2.1]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:334) ~[graphql-demo:3.2.1]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1358) ~[graphql-demo:3.2.1]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1347) ~[graphql-demo:3.2.1]
	at com.example.graph.ApplicationKt.main(Application.kt:16) ~[graphql-demo:na]
	at java.base@21/java.lang.invoke.LambdaForm$DMH/sa346b79c.invokeStaticInit(LambdaForm$DMH) ~[na:na]
Caused by: kotlin.reflect.jvm.internal.KotlinReflectionInternalError: Unresolved class: class com.example.graph.spring.MongockBeanDefinitionRegistrar$MongockRunnerSupport (kind = CLASS)
	at kotlin.reflect.jvm.internal.KClassImpl.createSyntheticClassOrFail(KClassImpl.kt:340) ~[graphql-demo:1.9.21-release-633]
	at kotlin.reflect.jvm.internal.KClassImpl.access$createSyntheticClassOrFail(KClassImpl.kt:49) ~[graphql-demo:1.9.21-release-633]
	at kotlin.reflect.jvm.internal.KClassImpl$Data$descriptor$2.invoke(KClassImpl.kt:67) ~[na:na]
	at kotlin.reflect.jvm.internal.KClassImpl$Data$descriptor$2.invoke(KClassImpl.kt:53) ~[na:na]
	at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:70) ~[na:na]
	at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:32) ~[graphql-demo:1.9.21-release-633]
	at kotlin.reflect.jvm.internal.KClassImpl$Data.getDescriptor(KClassImpl.kt:53) ~[graphql-demo:1.9.21-release-633]
	at kotlin.reflect.jvm.internal.KClassImpl.getDescriptor(KClassImpl.kt:193) ~[graphql-demo:1.9.21-release-633]
	at kotlin.reflect.jvm.internal.KClassImpl.getMemberScope$kotlin_reflection(KClassImpl.kt:202) ~[graphql-demo:1.9.21-release-633]
	at kotlin.reflect.jvm.internal.KClassImpl$Data$declaredNonStaticMembers$2.invoke(KClassImpl.kt:173) ~[na:na]
	at kotlin.reflect.jvm.internal.KClassImpl$Data$declaredNonStaticMembers$2.invoke(KClassImpl.kt:173) ~[na:na]
	at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:70) ~[na:na]
	at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:32) ~[graphql-demo:1.9.21-release-633]
	at kotlin.reflect.jvm.internal.KClassImpl$Data.getDeclaredNonStaticMembers(KClassImpl.kt:173) ~[graphql-demo:1.9.21-release-633]
	at kotlin.reflect.jvm.internal.KClassImpl$Data$allNonStaticMembers$2.invoke(KClassImpl.kt:182) ~[na:na]
	at kotlin.reflect.jvm.internal.KClassImpl$Data$allNonStaticMembers$2.invoke(KClassImpl.kt:182) ~[na:na]
	at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:70) ~[na:na]
	at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:32) ~[graphql-demo:1.9.21-release-633]
	at kotlin.reflect.jvm.internal.KClassImpl$Data.getAllNonStaticMembers(KClassImpl.kt:182) ~[graphql-demo:1.9.21-release-633]
	at kotlin.reflect.jvm.internal.KClassImpl$Data$allMembers$2.invoke(KClassImpl.kt:188) ~[na:na]
	at kotlin.reflect.jvm.internal.KClassImpl$Data$allMembers$2.invoke(KClassImpl.kt:188) ~[na:na]
	at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:70) ~[na:na]
	at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:32) ~[graphql-demo:1.9.21-release-633]
	at kotlin.reflect.jvm.internal.KClassImpl$Data.getAllMembers(KClassImpl.kt:188) ~[graphql-demo:1.9.21-release-633]
	at kotlin.reflect.jvm.internal.KClassImpl.getMembers(KClassImpl.kt:206) ~[graphql-demo:1.9.21-release-633]
	at org.springframework.data.util.KotlinBeanInfoFactory.getBeanInfo(KotlinBeanInfoFactory.java:64) ~[graphql-demo:3.2.1]
	at org.springframework.beans.CachedIntrospectionResults.getBeanInfo(CachedIntrospectionResults.java:222) ~[na:na]
	at org.springframework.beans.CachedIntrospectionResults.<init>(CachedIntrospectionResults.java:248) ~[na:na]
	at org.springframework.beans.CachedIntrospectionResults.forClass(CachedIntrospectionResults.java:157) ~[na:na]
	at org.springframework.beans.BeanWrapperImpl.getCachedIntrospectionResults(BeanWrapperImpl.java:162) ~[graphql-demo:6.1.2]
	at org.springframework.beans.BeanWrapperImpl.getLocalPropertyHandler(BeanWrapperImpl.java:193) ~[graphql-demo:6.1.2]
	at org.springframework.beans.BeanWrapperImpl.getLocalPropertyHandler(BeanWrapperImpl.java:58) ~[graphql-demo:6.1.2]
	at org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyHandler(AbstractNestablePropertyAccessor.java:739) ~[graphql-demo:6.1.2]
	at org.springframework.beans.AbstractNestablePropertyAccessor.isWritableProperty(AbstractNestablePropertyAccessor.java:565) ~[graphql-demo:6.1.2]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1686) ~[graphql-demo:6.1.2]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1433) ~[graphql-demo:6.1.2]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:598) ~[graphql-demo:6.1.2]
	... 41 common frames omitted

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)theme: aotAn issue related to Ahead-of-time processingtheme: kotlinAn issue related to Kotlin supporttype: bugA general bug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions