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

When a configuration properties bean is defined using a @Bean method, BindableRuntimeHintsRegistrar may incorrectly register hints for constructor binding #35564

Closed
wilkinsona opened this issue May 19, 2023 · 0 comments
Assignees
Labels
type: bug A general bug
Milestone

Comments

@wilkinsona
Copy link
Member

wilkinsona commented May 19, 2023

We have an example of this in our own code. SpringBootMockMvcBuilderCustomizer is defined using a @Bean method:

@Bean
@ConfigurationProperties(prefix = "spring.test.mockmvc")
public SpringBootMockMvcBuilderCustomizer springBootMockMvcBuilderCustomizer() {
return new SpringBootMockMvcBuilderCustomizer(this.context);
}

It has a single constructor:

/**
* Create a new {@link SpringBootMockMvcBuilderCustomizer} instance.
* @param context the source application context
*/
public SpringBootMockMvcBuilderCustomizer(WebApplicationContext context) {
Assert.notNull(context, "Context must not be null");
this.context = context;
}

When the class is the only information that's available, this makes it appear to be eligible for constructor binding. BindableRuntimeHintsRegistrar incorrectly determines that this is the case and generates the wrong hints.

This results in a failure like this when running the tests:

  JUnit Jupiter:WebMvcSliceTests:check()
    MethodSource [className = 'com.example.webmvc.WebMvcSliceTests', methodName = 'check', methodParameterTypes = '']
    => java.lang.IllegalStateException: Failed to load ApplicationContext for [AotMergedContextConfiguration@12e1b866 testClass = com.example.webmvc.WebMvcSliceTests, contextInitializerClass = com.example.webmvc.WebMvcSliceTests__TestContext005_ApplicationContextInitializer, original = [WebMergedContextConfiguration@73949a89 testClass = com.example.webmvc.WebMvcSliceTests, locations = [], classes = [com.example.webmvc.WebMvcApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceLocations = [], propertySourceProperties = ["org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@35bbe473, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@1bb6b6f8, org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@177e6019, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@584a392e, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.context.SpringBootTestAnnotation@4e0d46f], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]]
       org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:142)
       org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:127)
       org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependenciesInAotMode(DependencyInjectionTestExecutionListener.java:148)
       org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:94)
       org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:241)
       [...]
     Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mockMvcBuilder': Unsatisfied dependency expressed through method 'mockMvcBuilder' parameter 0: Error creating bean with name 'springBootMockMvcBuilderCustomizer': Runtime reflection is not supported for public void org.springframework.boot.test.autoconfigure.web.servlet.SpringBootMockMvcBuilderCustomizer.setAddFilters(boolean)
       org.springframework.beans.factory.aot.BeanInstanceSupplier.resolveArgument(BeanInstanceSupplier.java:315)
       org.springframework.beans.factory.aot.BeanInstanceSupplier.resolveArguments(BeanInstanceSupplier.java:258)
       org.springframework.beans.factory.aot.BeanInstanceSupplier.get(BeanInstanceSupplier.java:198)
       org.springframework.beans.factory.support.DefaultListableBeanFactory.obtainInstanceFromSupplier(DefaultListableBeanFactory.java:947)
       org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1214)
       [...]
     Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springBootMockMvcBuilderCustomizer': Runtime reflection is not supported for public void org.springframework.boot.test.autoconfigure.web.servlet.SpringBootMockMvcBuilderCustomizer.setAddFilters(boolean)
       org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:605)
       org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520)
       org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326)
       org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
       org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324)
       [...]
     Caused by: com.oracle.svm.core.jdk.UnsupportedFeatureError: Runtime reflection is not supported for public void org.springframework.boot.test.autoconfigure.web.servlet.SpringBootMockMvcBuilderCustomizer.setAddFilters(boolean)
       org.graalvm.nativeimage.builder/com.oracle.svm.core.util.VMError.unsupportedFeature(VMError.java:89)
       [email protected]/java.lang.reflect.Method.acquireMethodAccessor(Method.java:71)
       [email protected]/java.lang.reflect.Method.invoke(Method.java:566)
       org.springframework.boot.context.properties.bind.JavaBeanBinder$BeanProperty.setValue(JavaBeanBinder.java:397)
       org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:104)
       [...]
@wilkinsona wilkinsona added the type: bug A general bug label May 19, 2023
@wilkinsona wilkinsona added this to the 3.0.x milestone May 19, 2023
@wilkinsona wilkinsona modified the milestones: 3.0.x, 3.0.8 May 26, 2023
sobychacko added a commit to sobychacko/spring-cloud-stream that referenced this issue Sep 7, 2023
 - Earlier, we had to add Autowired on KafkaBinderConfigurationProperties constructor
   as there were some issues with runtime hints generation which caused issues when
   running an app in native mode. Spring Boot fixed these issues and we can remove
   this unnecessary Autowired from the constructor.

See the following issues from Spring Boot for more details.

spring-projects/spring-boot#34507
spring-projects/spring-boot#35564

Resolves spring-cloud#2640
omercelikceng pushed a commit to omercelikceng/spring-cloud-stream that referenced this issue Sep 14, 2023
 - Earlier, we had to add Autowired on KafkaBinderConfigurationProperties constructor
   as there were some issues with runtime hints generation which caused issues when
   running an app in native mode. Spring Boot fixed these issues and we can remove
   this unnecessary Autowired from the constructor.

See the following issues from Spring Boot for more details.

spring-projects/spring-boot#34507
spring-projects/spring-boot#35564

Resolves spring-cloud#2640
omercelikceng pushed a commit to omercelikceng/spring-cloud-stream that referenced this issue Sep 18, 2023
 - Earlier, we had to add Autowired on KafkaBinderConfigurationProperties constructor
   as there were some issues with runtime hints generation which caused issues when
   running an app in native mode. Spring Boot fixed these issues and we can remove
   this unnecessary Autowired from the constructor.

See the following issues from Spring Boot for more details.

spring-projects/spring-boot#34507
spring-projects/spring-boot#35564

Resolves spring-cloud#2640
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants