Overview

While allowing the TestContextAotGenerator to process all test classes within the spring-test module, I noticed several AOT processing failures for contexts loaded from XML config.

This issue serves as an umbrella issue for the team. If anyone wishes to investigate a particular problem, I'd be happy to provide steps to reproduce the issue.

Issues Encountered

  • When BeanDefinitionPropertyValueCodeGenerator.MapDelegate generates code for a Map, that map may contain instances of TypedStringValue resulting in a stack trace similar to the following that occurred while processing an ApplicationContext created from ExpressionUsageTests-context.xml in spring-test. We should likely replace typed string values with actual values before generating the map.
Caused by: java.lang.ClassCastException: class org.springframework.beans.factory.config.TypedStringValue cannot be cast to class java.lang.Comparable (org.springframework.beans.factory.config.TypedStringValue is in unnamed module of loader org.springframework.aot.test.generator.compile.CompileWithTargetClassAccessClassLoader @24a1c17f; java.lang.Comparable is in module java.base of loader 'bootstrap')
    at java.util.TreeMap.compare(TreeMap.java:1569) ~[?:?]
    at java.util.TreeMap.addEntryToEmptyMap(TreeMap.java:776) ~[?:?]
    at java.util.TreeMap.put(TreeMap.java:785) ~[?:?]
    at java.util.TreeMap.put(TreeMap.java:534) ~[?:?]
    at java.util.AbstractMap.putAll(AbstractMap.java:281) ~[?:?]
    at java.util.TreeMap.putAll(TreeMap.java:326) ~[?:?]
    at java.util.TreeMap.<init>(TreeMap.java:187) ~[?:?]
    at org.springframework.beans.factory.aot.BeanDefinitionPropertyValueCodeGenerator$MapDelegate.orderForCodeConsistency(BeanDefinitionPropertyValueCodeGenerator.java:497) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionPropertyValueCodeGenerator$MapDelegate.generateMapCode(BeanDefinitionPropertyValueCodeGenerator.java:471) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionPropertyValueCodeGenerator$MapDelegate.generateCode(BeanDefinitionPropertyValueCodeGenerator.java:457) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionPropertyValueCodeGenerator.generateCode(BeanDefinitionPropertyValueCodeGenerator.java:98) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionPropertyValueCodeGenerator.generateCode(BeanDefinitionPropertyValueCodeGenerator.java:90) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionPropertiesCodeGenerator.addPropertyValues(BeanDefinitionPropertiesCodeGenerator.java:182) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionPropertiesCodeGenerator.generateCode(BeanDefinitionPropertiesCodeGenerator.java:128) ~[main/:?]
    at org.springframework.beans.factory.aot.DefaultBeanRegistrationCodeFragments.generateSetBeanDefinitionPropertiesCode(DefaultBeanRegistrationCodeFragments.java:144) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanRegistrationCodeGenerator.generateCode(BeanRegistrationCodeGenerator.java:86) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.lambda$2(BeanDefinitionMethodGenerator.java:149) ~[main/:?]
    at org.springframework.aot.generate.GeneratedMethod.<init>(GeneratedMethod.java:48) ~[main/:?]
    at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:85) ~[main/:?]
    at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:72) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.generateBeanDefinitionMethod(BeanDefinitionMethodGenerator.java:143) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.generateBeanDefinitionMethod(BeanDefinitionMethodGenerator.java:115) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.lambda$2(BeanRegistrationsAotContribution.java:83) ~[main/:?]
    at java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[?:?]
    at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.generateRegisterMethod(BeanRegistrationsAotContribution.java:81) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.lambda$1(BeanRegistrationsAotContribution.java:67) ~[main/:?]
    at org.springframework.aot.generate.GeneratedMethod.<init>(GeneratedMethod.java:48) ~[main/:?]
    at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:85) ~[main/:?]
    at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:72) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.applyTo(BeanRegistrationsAotContribution.java:66) ~[main/:?]
    at org.springframework.context.aot.BeanFactoryInitializationAotContributions.applyTo(BeanFactoryInitializationAotContributions.java:78) ~[main/:?]
    at org.springframework.context.aot.ApplicationContextAotGenerator.lambda$0(ApplicationContextAotGenerator.java:58) ~[main/:?]
    at org.springframework.context.aot.ApplicationContextAotGenerator.withGeneratedClassHandler(ApplicationContextAotGenerator.java:66) ~[main/:?]
    at org.springframework.context.aot.ApplicationContextAotGenerator.processAheadOfTime(ApplicationContextAotGenerator.java:53) ~[main/:?]
    at org.springframework.test.context.aot.TestContextAotGenerator.processAheadOfTime(TestContextAotGenerator.java:149) ~[main/:?]

  • BeanDefinitionPropertyValueCodeGenerator likely needs a TypedStringValueDelegate, because without one we see stack traces similar to the following that occurred while processing an ApplicationContext created from SpringJUnit4ClassRunnerAppCtxTests-context.xml in spring-test.
Caused by: java.lang.IllegalArgumentException: 'type' org.springframework.beans.factory.config.TypedStringValue must be supported for instance code generation
    at org.springframework.beans.factory.aot.BeanDefinitionPropertyValueCodeGenerator.generateCode(BeanDefinitionPropertyValueCodeGenerator.java:102) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionPropertyValueCodeGenerator.generateCode(BeanDefinitionPropertyValueCodeGenerator.java:89) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionPropertiesCodeGenerator.addPropertyValues(BeanDefinitionPropertiesCodeGenerator.java:182) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionPropertiesCodeGenerator.generateCode(BeanDefinitionPropertiesCodeGenerator.java:128) ~[main/:?]
    at org.springframework.beans.factory.aot.DefaultBeanRegistrationCodeFragments.generateSetBeanDefinitionPropertiesCode(DefaultBeanRegistrationCodeFragments.java:144) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanRegistrationCodeGenerator.generateCode(BeanRegistrationCodeGenerator.java:86) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.lambda$2(BeanDefinitionMethodGenerator.java:149) ~[main/:?]
    at org.springframework.aot.generate.GeneratedMethod.<init>(GeneratedMethod.java:48) ~[main/:?]
    at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:85) ~[main/:?]
    at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:72) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.generateBeanDefinitionMethod(BeanDefinitionMethodGenerator.java:143) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.generateBeanDefinitionMethod(BeanDefinitionMethodGenerator.java:107) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.lambda$2(BeanRegistrationsAotContribution.java:83) ~[main/:?]
    at java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[?:?]
    at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.generateRegisterMethod(BeanRegistrationsAotContribution.java:81) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.lambda$1(BeanRegistrationsAotContribution.java:67) ~[main/:?]
    at org.springframework.aot.generate.GeneratedMethod.<init>(GeneratedMethod.java:48) ~[main/:?]
    at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:85) ~[main/:?]
    at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:72) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.applyTo(BeanRegistrationsAotContribution.java:66) ~[main/:?]
    at org.springframework.context.aot.BeanFactoryInitializationAotContributions.applyTo(BeanFactoryInitializationAotContributions.java:78) ~[main/:?]
    at org.springframework.context.aot.ApplicationContextAotGenerator.lambda$0(ApplicationContextAotGenerator.java:58) ~[main/:?]
    at org.springframework.context.aot.ApplicationContextAotGenerator.withGeneratedClassHandler(ApplicationContextAotGenerator.java:66) ~[main/:?]
    at org.springframework.context.aot.ApplicationContextAotGenerator.processAheadOfTime(ApplicationContextAotGenerator.java:53) ~[main/:?]
    at org.springframework.test.context.aot.TestContextAotGenerator.processAheadOfTime(TestContextAotGenerator.java:149) ~[main/:?]

  • An unresolved ResolvableType in BeanDefinitionPropertyValueCodeGenerator results in a stack trace similar to the following that occurred while processing an ApplicationContext created from transactionalTests-context.xml in spring-test.
Caused by: java.lang.IllegalArgumentException: 'type' ? must be supported for instance code generation
    at org.springframework.beans.factory.aot.BeanDefinitionPropertyValueCodeGenerator.generateCode(BeanDefinitionPropertyValueCodeGenerator.java:103) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionPropertyValueCodeGenerator$CollectionDelegate.generateCollectionOf(BeanDefinitionPropertyValueCodeGenerator.java:326) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionPropertyValueCodeGenerator$CollectionDelegate.generateCollectionCode(BeanDefinitionPropertyValueCodeGenerator.java:315) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionPropertyValueCodeGenerator$CollectionDelegate.generateCode(BeanDefinitionPropertyValueCodeGenerator.java:309) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionPropertyValueCodeGenerator.generateCode(BeanDefinitionPropertyValueCodeGenerator.java:98) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionPropertyValueCodeGenerator.generateCode(BeanDefinitionPropertyValueCodeGenerator.java:90) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionPropertiesCodeGenerator.addPropertyValues(BeanDefinitionPropertiesCodeGenerator.java:182) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionPropertiesCodeGenerator.generateCode(BeanDefinitionPropertiesCodeGenerator.java:128) ~[main/:?]
    at org.springframework.beans.factory.aot.DefaultBeanRegistrationCodeFragments.generateSetBeanDefinitionPropertiesCode(DefaultBeanRegistrationCodeFragments.java:144) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanRegistrationCodeGenerator.generateCode(BeanRegistrationCodeGenerator.java:86) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.lambda$2(BeanDefinitionMethodGenerator.java:149) ~[main/:?]
    at org.springframework.aot.generate.GeneratedMethod.<init>(GeneratedMethod.java:48) ~[main/:?]
    at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:85) ~[main/:?]
    at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:72) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.generateBeanDefinitionMethod(BeanDefinitionMethodGenerator.java:143) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.generateBeanDefinitionMethod(BeanDefinitionMethodGenerator.java:107) ~[main/:?]
    at org.springframework.beans.factory.aot.DefaultBeanRegistrationCodeFragments.generateValueCode(DefaultBeanRegistrationCodeFragments.java:157) ~[main/:?]
    at org.springframework.beans.factory.aot.DefaultBeanRegistrationCodeFragments.lambda$0(DefaultBeanRegistrationCodeFragments.java:143) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionPropertiesCodeGenerator.addPropertyValues(BeanDefinitionPropertiesCodeGenerator.java:180) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionPropertiesCodeGenerator.generateCode(BeanDefinitionPropertiesCodeGenerator.java:128) ~[main/:?]
    at org.springframework.beans.factory.aot.DefaultBeanRegistrationCodeFragments.generateSetBeanDefinitionPropertiesCode(DefaultBeanRegistrationCodeFragments.java:144) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanRegistrationCodeGenerator.generateCode(BeanRegistrationCodeGenerator.java:86) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.lambda$2(BeanDefinitionMethodGenerator.java:149) ~[main/:?]
    at org.springframework.aot.generate.GeneratedMethod.<init>(GeneratedMethod.java:48) ~[main/:?]
    at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:85) ~[main/:?]
    at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:72) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.generateBeanDefinitionMethod(BeanDefinitionMethodGenerator.java:143) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.generateBeanDefinitionMethod(BeanDefinitionMethodGenerator.java:107) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.lambda$2(BeanRegistrationsAotContribution.java:83) ~[main/:?]
    at java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[?:?]
    at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.generateRegisterMethod(BeanRegistrationsAotContribution.java:81) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.lambda$1(BeanRegistrationsAotContribution.java:67) ~[main/:?]
    at org.springframework.aot.generate.GeneratedMethod.<init>(GeneratedMethod.java:48) ~[main/:?]
    at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:85) ~[main/:?]
    at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:72) ~[main/:?]
    at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.applyTo(BeanRegistrationsAotContribution.java:66) ~[main/:?]
    at org.springframework.context.aot.BeanFactoryInitializationAotContributions.applyTo(BeanFactoryInitializationAotContributions.java:78) ~[main/:?]
    at org.springframework.context.aot.ApplicationContextAotGenerator.lambda$0(ApplicationContextAotGenerator.java:58) ~[main/:?]
    at org.springframework.context.aot.ApplicationContextAotGenerator.withGeneratedClassHandler(ApplicationContextAotGenerator.java:66) ~[main/:?]
    at org.springframework.context.aot.ApplicationContextAotGenerator.processAheadOfTime(ApplicationContextAotGenerator.java:53) ~[main/:?]
    at org.springframework.test.context.aot.TestContextAotGenerator.processAheadOfTime(TestContextAotGenerator.java:149) ~[main/:?]

Comment From: snicoll

Is this some sort of meta-issues or something? I see two separate issues and I am wondering if that wouldn't be more clear if they were split. The suggestion on adding support for TypedStringValue for code generation looks legit to me.

The second issue is about not exposing a type for the bean. What part of it is specific to XML configuration?

Comment From: sbrannen

Is this some sort of meta-issues or something?

Yes, as stated in the description: "This issue serves as an umbrella issue for the team."

I see two separate issues and I am wondering if that wouldn't be more clear if they were split. The suggestion on adding support for TypedStringValue for code generation looks legit to me.

Sure, I can split them up. @jhoeller also stated elsewhere that it be worth investigating the TypedStringValue issues.

As discussed in the team during your absence, I created the umbrella issue so that the issues I'd discovered would not get lost.

The second issue is about not exposing a type for the bean. What part of it is specific to XML configuration?

I don't know. I didn't debug it. I encountered it only when running AOT processing against test classes in spring-test that use XML config. So I added it to this umbrella issue.

Comment From: sbrannen

Superseded by:

  • 29074

  • 29075