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

getTypeForFactoryMethod should catch NoClassDefFoundError #33075

Closed
HzjNeverStop opened this issue Jun 20, 2024 · 4 comments
Closed

getTypeForFactoryMethod should catch NoClassDefFoundError #33075

HzjNeverStop opened this issue Jun 20, 2024 · 4 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Milestone

Comments

@HzjNeverStop
Copy link

HzjNeverStop commented Jun 20, 2024

Environment: SpringBoot 3.2.6

In the following scenario, this behavior makes it difficult to locate the root cause of the problem:
For example, two Configuration classes A and B register two BeanDefinitions A and B with the same beanName, using @ConditionalOnMissingBean to ensure that only one BeanDefinition is effective.

When another Configuration class C registers a BeanDefinition, and this BeanDefinition uses a class that cannot be found, the following situation may occur:

  1. Configuration class A registers BeanDefinition A;
  2. Configuration class C registers BeanDefinition C;
  3. When Configuration class B registers BeanDefinition B, during the evaluation of the OnBeanCondition getBeanNamesForType process, an empty set array is returned because an exception is thrown while parsing BeanDefinition C in the OnBeanCondition#getBeanNamesForType method.

As a result, the BeanDefinition B registered by Configuration class B is not skipped, causing springboot to throw a BeanDefinitionOverrideException. The root cause exception of the problem is swallowed in the OnBeanCondition#getBeanNamesForType method, making it difficult to locate the problem.

The swallowed stack trace:

java.lang.NoClassDefFoundError: javax/servlet/Filter
    at java.base/java.lang.ClassLoader.defineClass1(Native Method)
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1017)
    at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:592)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:467)
    at java.base/sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:114)
    at java.base/sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:125)
    at java.base/sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
    at java.base/sun.reflect.generics.visitor.Reifier.reifyTypeArguments(Reifier.java:68)
    at java.base/sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:138)
    at java.base/sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
    at java.base/sun.reflect.generics.repository.MethodRepository.computeReturnType(MethodRepository.java:75)
    at java.base/sun.reflect.generics.repository.MethodRepository.getReturnType(MethodRepository.java:66)
    at java.base/java.lang.reflect.Method.getGenericReturnType(Method.java:295)
    at org.springframework.core.MethodParameter.getGenericParameterType(MethodParameter.java:516)
    at org.springframework.core.SerializableTypeWrapper$MethodParameterTypeProvider.getType(SerializableTypeWrapper.java:297)
    at org.springframework.core.SerializableTypeWrapper.forTypeProvider(SerializableTypeWrapper.java:106)
    at org.springframework.core.ResolvableType.forType(ResolvableType.java:1458)
    at org.springframework.core.ResolvableType.forMethodParameter(ResolvableType.java:1379)
    at org.springframework.core.ResolvableType.forMethodParameter(ResolvableType.java:1361)
    at org.springframework.core.ResolvableType.forMethodParameter(ResolvableType.java:1328)
    at org.springframework.core.ResolvableType.forMethodReturnType(ResolvableType.java:1273)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:817)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:682)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:653)
    at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1687)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:562)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:534)
    at org.springframework.boot.autoconfigure.condition.OnBeanCondition.collectBeanNamesForType(OnBeanCondition.java:247)
    at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getBeanNamesForType(OnBeanCondition.java:240)
    at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getBeanNamesForType(OnBeanCondition.java:230)
    at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchingBeans(OnBeanCondition.java:183)
    at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchOutcome(OnBeanCondition.java:158)
    at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47)
    at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108)
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:183)
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:144)
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:120)
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:429)
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:290)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:349)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:118)

The spring boot failure reason:

***************************
APPLICATION FAILED TO START
***************************

Description:

The bean 'propertySourcesPlaceholderConfigurer', defined in class path resource [org/springframework/boot/autoconfigure/context/PropertyPlaceholderAutoConfiguration.class], could not be registered. A bean with that name has already been defined in class path resource [com/alipay/sofa/boot/autoconfigure/core/AlipayBootAutoConfiguration$AlipayPropertyPlaceholderAutoConfiguration.class] and overriding is disabled.

Action:

Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Jun 20, 2024
@philwebb
Copy link
Member

@HzjNeverStop Are you able to provide a sample application? I'm having a hard time following the example you're describing. Swallowing the exception is intentional since we assume that if the class isn't available there can be no beans of that type.

@philwebb philwebb added the status: waiting-for-feedback We need additional information before we can continue label Jun 20, 2024
@HzjNeverStop
Copy link
Author

HzjNeverStop commented Jun 20, 2024

@HzjNeverStop Are you able to provide a sample application? I'm having a hard time following the example you're describing. Swallowing the exception is intentional since we assume that if the class isn't available there can be no beans of that type.

I tried to reproduce this issue, which occurs when the method return type is a generic structure.
You can reproduce this using the github demo (after packaging with mvn package, start the SpringBoot program using java -jar).

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Jun 20, 2024
@wilkinsona wilkinsona added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged or decided on status: feedback-provided Feedback has been provided labels Jun 20, 2024
@wilkinsona
Copy link
Member

wilkinsona commented Jun 20, 2024

Thanks, @HzjNeverStop. Something's definitely wrong here. The sample has:

@AutoConfiguration(before = DemoBAutoConfiguration.class)
public class DemoAAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public DemoBean demoBean() {
        return new DemoBean("from DemoAAutoConfiguration");
    }
}

and

@AutoConfiguration
public class DemoBAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public DemoBean demoBean() {
        return new DemoBean("from DemoBAutoConfiguration");
    }
}

Yet both demoBean methods result in the bean being defined. The condition evaluation report shows that no beans of that type were found both times it was evaluated:

   DemoAAutoConfiguration#demoBean matched:
      - @ConditionalOnMissingBean (types: com.example.spring_demo.DemoBean; SearchStrategy: all) did not find any beans (OnBeanCondition)

   DemoBAutoConfiguration#demoBean matched:
      - @ConditionalOnMissingBean (types: com.example.spring_demo.DemoBean; SearchStrategy: all) did not find any beans (OnBeanCondition)

Stack trace of the exception that's swallowed:

java.lang.NoClassDefFoundError: javax/servlet/Filter
	at java.base/java.lang.ClassLoader.defineClass1(Native Method)
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1017)
	at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
	at java.base/java.net.URLClassLoader.defineClass(URLClassLoader.java:524)
	at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:427)
	at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:421)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
	at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:420)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:592)
	at org.springframework.boot.loader.net.protocol.jar.JarUrlClassLoader.loadClass(JarUrlClassLoader.java:103)
	at org.springframework.boot.loader.launch.LaunchedClassLoader.loadClass(LaunchedClassLoader.java:91)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:467)
	at java.base/sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:114)
	at java.base/sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:125)
	at java.base/sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
	at java.base/sun.reflect.generics.visitor.Reifier.reifyTypeArguments(Reifier.java:68)
	at java.base/sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:138)
	at java.base/sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
	at java.base/sun.reflect.generics.repository.MethodRepository.computeReturnType(MethodRepository.java:75)
	at java.base/sun.reflect.generics.repository.MethodRepository.getReturnType(MethodRepository.java:66)
	at java.base/java.lang.reflect.Method.getGenericReturnType(Method.java:295)
	at org.springframework.core.MethodParameter.getGenericParameterType(MethodParameter.java:516)
	at org.springframework.core.SerializableTypeWrapper$MethodParameterTypeProvider.getType(SerializableTypeWrapper.java:297)
	at org.springframework.core.SerializableTypeWrapper.forTypeProvider(SerializableTypeWrapper.java:106)
	at org.springframework.core.ResolvableType.forType(ResolvableType.java:1458)
	at org.springframework.core.ResolvableType.forMethodParameter(ResolvableType.java:1379)
	at org.springframework.core.ResolvableType.forMethodParameter(ResolvableType.java:1361)
	at org.springframework.core.ResolvableType.forMethodParameter(ResolvableType.java:1328)
	at org.springframework.core.ResolvableType.forMethodReturnType(ResolvableType.java:1273)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:817)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:682)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:653)
	at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1687)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:562)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:534)
	at org.springframework.boot.autoconfigure.condition.OnBeanCondition.collectBeanNamesForType(OnBeanCondition.java:247)
	at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getBeanNamesForType(OnBeanCondition.java:240)
	at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getBeanNamesForType(OnBeanCondition.java:230)
	at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchingBeans(OnBeanCondition.java:183)
	at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchOutcome(OnBeanCondition.java:158)
	at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47)
	at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108)
	at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:183)
	at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:144)
	at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:120)
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:429)
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:290)
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:349)
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:118)
	at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:788)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:606)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:335)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352)
	at com.example.spring_demo.SpringDemoApplication.main(SpringDemoApplication.java:10)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:91)
	at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:53)
	at org.springframework.boot.loader.launch.JarLauncher.main(JarLauncher.java:58)
Caused by: java.lang.ClassNotFoundException: javax.servlet.Filter
	at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:445)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:592)
	at org.springframework.boot.loader.net.protocol.jar.JarUrlClassLoader.loadClass(JarUrlClassLoader.java:103)
	at org.springframework.boot.loader.launch.LaunchedClassLoader.loadClass(LaunchedClassLoader.java:91)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
	... 66 more

@wilkinsona
Copy link
Member

I've tried patching Framework so that AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod catches NoClassDefFoundError and returns null. This seems aligned with its javadoc that states that it will return "the type for the bean if determinable, or null otherwise". With this change in place, the sample then fails like this:

2024-06-20T09:49:47.393+01:00 ERROR 46247 --- [spring-demo] [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'errorBean' defined in class path resource [com/example/spring_demo/DemoCAutoConfiguration.class]: Failed to instantiate [org.springframework.boot.web.servlet.FilterRegistrationBean]: Factory method 'errorBean' threw exception with message: javax/servlet/Filter
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:648) ~[spring-beans-6.1.8.jar!/:6.1.8]
	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:485) ~[spring-beans-6.1.8.jar!/:6.1.8]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1341) ~[!/:6.1.8]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1171) ~[!/:6.1.8]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:561) ~[!/:6.1.8]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[!/:6.1.8]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337) ~[spring-beans-6.1.8.jar!/:6.1.8]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.1.8.jar!/:6.1.8]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335) ~[spring-beans-6.1.8.jar!/:6.1.8]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.1.8.jar!/:6.1.8]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975) ~[spring-beans-6.1.8.jar!/:6.1.8]
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:962) ~[spring-context-6.1.8.jar!/:6.1.8]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:624) ~[spring-context-6.1.8.jar!/:6.1.8]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-3.2.6.jar!/:3.2.6]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) ~[spring-boot-3.2.6.jar!/:3.2.6]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:335) ~[spring-boot-3.2.6.jar!/:3.2.6]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363) ~[spring-boot-3.2.6.jar!/:3.2.6]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352) ~[spring-boot-3.2.6.jar!/:3.2.6]
	at com.example.spring_demo.SpringDemoApplication.main(SpringDemoApplication.java:10) ~[!/:0.0.1-SNAPSHOT]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
	at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:91) ~[spring-demo-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
	at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:53) ~[spring-demo-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
	at org.springframework.boot.loader.launch.JarLauncher.main(JarLauncher.java:58) ~[spring-demo-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.web.servlet.FilterRegistrationBean]: Factory method 'errorBean' threw exception with message: javax/servlet/Filter
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:177) ~[spring-beans-6.1.8.jar!/:6.1.8]
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:644) ~[spring-beans-6.1.8.jar!/:6.1.8]
	... 25 common frames omitted
Caused by: java.lang.NoClassDefFoundError: javax/servlet/Filter
	at java.base/java.lang.ClassLoader.defineClass1(Native Method) ~[na:na]
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1017) ~[na:na]
	at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150) ~[na:na]
	at java.base/java.net.URLClassLoader.defineClass(URLClassLoader.java:524) ~[na:na]
	at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:427) ~[na:na]
	at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:421) ~[na:na]
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:712) ~[na:na]
	at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:420) ~[na:na]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:592) ~[na:na]
	at org.springframework.boot.loader.net.protocol.jar.JarUrlClassLoader.loadClass(JarUrlClassLoader.java:103) ~[spring-demo-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
	at org.springframework.boot.loader.launch.LaunchedClassLoader.loadClass(LaunchedClassLoader.java:91) ~[spring-demo-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525) ~[na:na]
	at com.example.spring_demo.DemoCAutoConfiguration.errorBean(DemoCAutoConfiguration.java:17) ~[!/:0.0.1-SNAPSHOT]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:140) ~[spring-beans-6.1.8.jar!/:6.1.8]
	... 26 common frames omitted
Caused by: java.lang.ClassNotFoundException: javax.servlet.Filter
	at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:445) ~[na:na]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:592) ~[na:na]
	at org.springframework.boot.loader.net.protocol.jar.JarUrlClassLoader.loadClass(JarUrlClassLoader.java:103) ~[spring-demo-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
	at org.springframework.boot.loader.launch.LaunchedClassLoader.loadClass(LaunchedClassLoader.java:91) ~[spring-demo-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525) ~[na:na]
	... 44 common frames omitted

I think this is exactly what we want. Unlike the exception above that's swallowed, the failure here precisely pinpoints the cause of the problem as it identifies errorBean as the cause.

We'll transfer this to the Framework team so that they can consider if they want to make a change here.

@wilkinsona wilkinsona removed the type: bug A general bug label Jun 20, 2024
@bclozel bclozel transferred this issue from spring-projects/spring-boot Jun 20, 2024
@bclozel bclozel added status: waiting-for-triage An issue we've not yet triaged or decided on in: core Issues in core modules (aop, beans, core, context, expression) labels Jun 20, 2024
@jhoeller jhoeller added type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Jun 20, 2024
@jhoeller jhoeller self-assigned this Jun 20, 2024
@jhoeller jhoeller added this to the 6.1.11 milestone Jun 20, 2024
@jhoeller jhoeller changed the title The OnBeanCondition#getBeanNamesForType method swallows the ClassNotFoundException exception. getTypeForFactoryMethod should catch NoClassDefFoundError Jun 20, 2024
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) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

6 participants