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

ConstructorResolver rejects a candidate if the parameter value is null #31495

Closed
sbrannen opened this issue Oct 25, 2023 · 4 comments
Closed
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) theme: aot An issue related to Ahead-of-time processing type: bug A general bug
Milestone

Comments

@sbrannen
Copy link
Member

sbrannen commented Oct 25, 2023

Now that #31472 has been resolved, AOT processing for Spr9799XmlConfigTests (in spring-test) fails with the following stack trace when run via AotIntegrationTests#endToEndTestsForEntireSpringTestModule().

org.springframework.test.context.aot.TestContextAotException: Failed to generate AOT artifacts for test classes [org.springframework.test.context.junit4.spr9799.Spr9799XmlConfigTests]
	at org.springframework.test.context.aot.TestContextAotGenerator.lambda$10(TestContextAotGenerator.java:284)
	at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721)
	at org.springframework.util.MultiValueMapAdapter.forEach(MultiValueMapAdapter.java:179)
	at org.springframework.test.context.aot.TestContextAotGenerator.processAheadOfTime(TestContextAotGenerator.java:243)
	at org.springframework.test.context.aot.TestContextAotGenerator.processAheadOfTime(TestContextAotGenerator.java:205)
	at org.springframework.test.context.aot.AotIntegrationTests.endToEndTestsForEntireSpringTestModule(AotIntegrationTests.java:151)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.springframework.core.test.tools.CompileWithForkedClassLoaderExtension.intercept(CompileWithForkedClassLoaderExtension.java:97)
	at org.springframework.core.test.tools.CompileWithForkedClassLoaderExtension.interceptTestMethod(CompileWithForkedClassLoaderExtension.java:83)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Caused by: org.springframework.test.context.aot.TestContextAotException: Failed to process test class [org.springframework.test.context.junit4.spr9799.Spr9799XmlConfigTests] for AOT
	at org.springframework.test.context.aot.TestContextAotGenerator.processAheadOfTime(TestContextAotGenerator.java:321)
	at org.springframework.test.context.aot.TestContextAotGenerator.lambda$10(TestContextAotGenerator.java:276)
	... 10 more
Caused by: java.lang.IllegalStateException: No constructor or factory method candidate found for Root bean: class [org.springframework.web.servlet.handler.MappedInterceptor]; scope=singleton; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodNames=null; destroyMethodNames=null and argument types [?, org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor]
	at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorOrFactoryMethod(ConstructorResolver.java:994)
	at org.springframework.beans.factory.support.RegisteredBean.resolveConstructorOrFactoryMethod(RegisteredBean.java:212)
	at org.springframework.util.function.SingletonSupplier.get(SingletonSupplier.java:106)
	at org.springframework.beans.factory.aot.DefaultBeanRegistrationCodeFragments.getTarget(DefaultBeanRegistrationCodeFragments.java:80)
	at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.generateBeanDefinitionMethod(BeanDefinitionMethodGenerator.java:85)
	at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.lambda$3(BeanRegistrationsAotContribution.java:90)
	at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721)
	at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.generateRegisterBeanDefinitionsMethod(BeanRegistrationsAotContribution.java:88)
	at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.lambda$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.context.aot.BeanFactoryInitializationAotContributions.applyTo(BeanFactoryInitializationAotContributions.java:78)
	at org.springframework.context.aot.ApplicationContextAotGenerator.lambda$0(ApplicationContextAotGenerator.java:58)
	at org.springframework.context.aot.ApplicationContextAotGenerator.withCglibClassHandler(ApplicationContextAotGenerator.java:67)
	at org.springframework.context.aot.ApplicationContextAotGenerator.processAheadOfTime(ApplicationContextAotGenerator.java:53)
	at org.springframework.test.context.aot.TestContextAotGenerator.processAheadOfTime(TestContextAotGenerator.java:318)
	... 11 more
@sbrannen sbrannen added status: waiting-for-triage An issue we've not yet triaged or decided on theme: aot An issue related to Ahead-of-time processing in: web Issues in web modules (web, webmvc, webflux, websocket) labels Oct 25, 2023
@snicoll
Copy link
Member

snicoll commented Oct 25, 2023

What does the generated code for MappedInterceptor look like?

I can see it sets the first argument to null and then a reference to a ConversionServiceExposingInterceptor bean which is an HandlerInterceptor so constructor resolution should find a matching constructor there.

@sbrannen
Copy link
Member Author

What does the generated code for MappedInterceptor look like?

It doesn't get that far. It fails while attempting to generate code.

@snicoll
Copy link
Member

snicoll commented Oct 25, 2023

That's the null there indeed. Replacing that with an empty String array is enough to get past the issue. With null we don't have any type matching, but I believe there might be some sort of fallback to try considering that all 5 constructors take a String[] as the first argument.

@snicoll snicoll added type: bug A general bug in: core Issues in core modules (aop, beans, core, context, expression) and removed status: waiting-for-triage An issue we've not yet triaged or decided on in: web Issues in web modules (web, webmvc, webflux, websocket) labels Oct 25, 2023
@snicoll snicoll self-assigned this Oct 25, 2023
@snicoll snicoll added this to the 6.1.0-RC2 milestone Oct 25, 2023
@snicoll snicoll changed the title No constructor or factory method candidate found for Root bean class MappedInterceptor ConstructorResolver rejects a candidate if the parameter value is null Oct 25, 2023
@snicoll
Copy link
Member

snicoll commented Oct 25, 2023

This was an interesting dive in ConstructorResolver. As a null value does not carry a type, it breaks any attempt to match a constructor. Ignoring the null value and proceeding with the non-null value is enough to make progress, including supporting this use case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) theme: aot An issue related to Ahead-of-time processing type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants