Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document why complex object structure are not supported as paremeters or properties by AOT #32273

Closed
Christopher-Chianelli opened this issue Feb 15, 2024 · 2 comments
Assignees
Labels
theme: aot An issue related to Ahead-of-time processing type: documentation A documentation task
Milestone

Comments

@Christopher-Chianelli
Copy link

Christopher-Chianelli commented Feb 15, 2024

Affects: 6.1.3


A bean definition that uses non-common value types like this:

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        RootBeanDefinition beanDefinition = new RootBeanDefinition(MyBean.class);
        beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(new MyBeanRecord("Bob", 12));
        registry.registerBeanDefinition("MyBean", beanDefinition);
    }

will cause a ValueCodeGeneration exception.
Since this use case is intentionally unsupported (see #32214 (comment)), a helpful error message saying "ConstructorArgumentValues do not support code generation for arguments of type (MyBeanRecord)" should be thrown instead, similar to what happens with instance suppliers.

Demo: https://github.com/Christopher-Chianelli/issue-reproducer/tree/constructor-argument-value-unsupported/demo

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Feb 15, 2024
@jhoeller jhoeller added the in: core Issues in core modules (aop, beans, core, context, expression) label Feb 15, 2024
@snicoll
Copy link
Member

snicoll commented Feb 15, 2024

It's not really the same thing. The issue you've referenced is a limitation of a supported construct of the core container. Creating a bean definition with an instance supplier is totally supported but, for obvious reasons, can't be supported by the AOT engine.

Providing complex object structure to a BeanDefinition is not idiomatic at all. The bean definition is an abstraction on top of several models, including our XML namespace where you can't obviously pass such an object. The idiomatic way to provide such object is via factory, or a bean reference.

"ConstructorArgumentValues do not support code generation for arguments of type (MyBeanRecord)" should be thrown instead, similar to #29556.

I disagree with that. There's nothing specific with ConstructorArgumentValues here. That being said, I can see how the ultimate exception thrown at the user can be rephrased by referencing to what I've just explained.

@snicoll snicoll added type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Feb 15, 2024
@snicoll snicoll added this to the 6.x Backlog milestone Feb 15, 2024
@snicoll snicoll added the theme: aot An issue related to Ahead-of-time processing label Feb 15, 2024
@snicoll snicoll changed the title Fail more explicitly when AOT attempts to handle a bean definition that uses a ConstructorArgumentValue that is not a common value type Fail more explicitly when AOT attempts to generate a value that is not supported, such as a complex object structure Feb 15, 2024
@snicoll
Copy link
Member

snicoll commented Jun 3, 2024

With the work going on in #32777 this will generate the following:

org.springframework.beans.factory.aot.AotBeanProcessingFailedException: Error processing bean with name 'MyBean': failed to generate code for bean definition

	at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.lambda$generateRegisterBeanDefinitionsMethod$2(BeanRegistrationsAotContribution.java:101)
	at java.base/java.lang.Iterable.forEach(Iterable.java:75)
	at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.generateRegisterBeanDefinitionsMethod(BeanRegistrationsAotContribution.java:88)
	at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.lambda$applyTo$1(BeanRegistrationsAotContribution.java:73)
	at org.springframework.aot.generate.GeneratedMethod.<init>(GeneratedMethod.java:54)
	at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:112)
	at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:89)
	at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.applyTo(BeanRegistrationsAotContribution.java:72)
	at org.springframework.beans.factory.aot.BeanRegistrationsAotContributionTests.applyToFailingWrapsValueCodeGeneration2(BeanRegistrationsAotContributionTests.java:205)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Caused by: org.springframework.aot.generate.ValueCodeGenerationException: Failed to generate code for 'MyBeanRecord[name=Bob, age=12]' with type class com.example.MyBeanRecord
	at org.springframework.aot.generate.ValueCodeGenerator.generateCode(ValueCodeGenerator.java:116)
	at org.springframework.beans.factory.aot.BeanDefinitionPropertiesCodeGenerator.generateValue(BeanDefinitionPropertiesCodeGenerator.java:269)
	at org.springframework.beans.factory.aot.BeanDefinitionPropertiesCodeGenerator.lambda$addConstructorArgumentValues$3(BeanDefinitionPropertiesCodeGenerator.java:191)
	at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721)
	at java.base/java.util.Collections$UnmodifiableMap.forEach(Collections.java:1553)
	at org.springframework.beans.factory.aot.BeanDefinitionPropertiesCodeGenerator.addConstructorArgumentValues(BeanDefinitionPropertiesCodeGenerator.java:188)
	at org.springframework.beans.factory.aot.BeanDefinitionPropertiesCodeGenerator.generateCode(BeanDefinitionPropertiesCodeGenerator.java:134)
	at org.springframework.beans.factory.aot.DefaultBeanRegistrationCodeFragments.generateSetBeanDefinitionPropertiesCode(DefaultBeanRegistrationCodeFragments.java:180)
	at org.springframework.beans.factory.aot.BeanRegistrationCodeGenerator.generateCode(BeanRegistrationCodeGenerator.java:81)
	at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.lambda$generateBeanDefinitionMethod$3(BeanDefinitionMethodGenerator.java:176)
	at org.springframework.aot.generate.GeneratedMethod.<init>(GeneratedMethod.java:54)
	at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:112)
	at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:89)
	at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.generateBeanDefinitionMethod(BeanDefinitionMethodGenerator.java:169)
	at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.generateBeanDefinitionMethod(BeanDefinitionMethodGenerator.java:89)
	at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.lambda$generateRegisterBeanDefinitionsMethod$2(BeanRegistrationsAotContribution.java:91)
	... 11 more
Caused by: org.springframework.aot.generate.UnsupportedTypeValueCodeGenerationException: Code generation does not support com.example.MyBeanRecord
	at org.springframework.aot.generate.ValueCodeGenerator.generateCode(ValueCodeGenerator.java:113)
	... 26 more

Let's rephrase this to have a section in the reference doc that rather explains why this exception is thrown. Conveying that in the exception message is not really practical.

@snicoll snicoll added type: documentation A documentation task and removed in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement labels Jun 3, 2024
@snicoll snicoll changed the title Fail more explicitly when AOT attempts to generate a value that is not supported, such as a complex object structure Document why complex object structure are not supported as paremeters or properties by AOT Jun 3, 2024
@snicoll snicoll self-assigned this Jun 3, 2024
@snicoll snicoll modified the milestones: 6.x Backlog, 6.1.9 Jun 4, 2024
@snicoll snicoll closed this as completed in 7102c33 Jun 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
theme: aot An issue related to Ahead-of-time processing type: documentation A documentation task
Projects
None yet
Development

No branches or pull requests

4 participants