Skip to content

Periodic NoClassDefFoundError: FatalBeanException caused by StackOverFlowException [SPR-10261] #14894

Closed
@spring-projects-issues

Description

@spring-projects-issues

Rob Winch opened SPR-10261 and commented

Despite having consistent Spring versions and ensuring I have spring-core-3.2.1.RELEASE.jar on the classpath, when loading Java Configuration, I occassionally get the following Error:

java.lang.NoClassDefFoundError: org.springframework.beans.FatalBeanException
	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:581)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1029)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:925)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:490)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
	at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:73)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
	at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:77)
	at org.codehaus.groovy.reflection.CachedConstructor.doConstructorInvoke(CachedConstructor.java:71)
	at org.codehaus.groovy.runtime.callsite.ConstructorSite.callConstructor(ConstructorSite.java:42)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:54)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:182)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:190)
	at groovy.groovy.GroovyReturnsSubclassTests.returnsSubclass(GroovyReturnsSubclassTests.groovy:16)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

This seems to be associated with a StackOverFlowException where the stack looks something like the following:

                                                                                ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(Object, Method, Object[], MethodProxy) line: 297	
                                                                GroovyReturnsSubclassTests$MyConfig$$EnhancerByCGLIB$$3aca3be8.builder() line: not available	
                                                                                                    GroovyReturnsSubclassTests$MyConfig$$EnhancerByCGLIB$$3aca3be8(GroovyReturnsSubclassTests$MyConfig).builder() line: not available	
                                                                        GroovyReturnsSubclassTests$MyConfig$$EnhancerByCGLIB$$3aca3be8.CGLIB$builder$6() line: not available	
                                                                                                                GroovyReturnsSubclassTests$MyConfig$$EnhancerByCGLIB$$3aca3be8$$FastClassByCGLIB$$2a4c4776.invoke(int, Object, Object[]) line: not available	
                        MethodProxy.invokeSuper(Object, Object[]) line: 228	
                                                                                ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(Object, Method, Object[], MethodProxy) line: 285	
                                                                GroovyReturnsSubclassTests$MyConfig$$EnhancerByCGLIB$$3aca3be8.builder() line: not available	
                                                                NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]	
                            NativeMethodAccessorImpl.invoke(Object, Object[]) line: 57	
                                DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43	
            Method.invoke(Object, Object...) line: 601	
                                                                                                                                CglibSubclassingInstantiationStrategy(SimpleInstantiationStrategy).instantiate(RootBeanDefinition, String, BeanFactory, Object, Method, Object[]) line: 160	
                                                                    ConstructorResolver.instantiateUsingFactoryMethod(String, RootBeanDefinition, Object[]) line: 570	
                                                                                                                DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).instantiateUsingFactoryMethod(String, RootBeanDefinition, Object[]) line: 1029	
                                                                                                    DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBeanInstance(String, RootBeanDefinition, Object[]) line: 925	
                                                                                                DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).doCreateBean(String, RootBeanDefinition, Object[]) line: 490	
                                                                                            DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBean(String, RootBeanDefinition, Object[]) line: 461	
                AbstractBeanFactory$1.getObject() line: 295	
                                                                        DefaultListableBeanFactory(DefaultSingletonBeanRegistry).getSingleton(String, ObjectFactory) line: 223	
                                                                            DefaultListableBeanFactory(AbstractBeanFactory).doGetBean(String, Class<T>, Object[], boolean) line: 292	
                                            DefaultListableBeanFactory(AbstractBeanFactory).getBean(String) line: 194	
                                                                                ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(Object, Method, Object[], MethodProxy) line: 297	
                                                                GroovyReturnsSubclassTests$MyConfig$$EnhancerByCGLIB$$3aca3be8.builder() line: not available	
                                                                                                    GroovyReturnsSubclassTests$MyConfig$$EnhancerByCGLIB$$3aca3be8(GroovyReturnsSubclassTests$MyConfig).builder() line: not available	
                                                                        GroovyReturnsSubclassTests$MyConfig$$EnhancerByCGLIB$$3aca3be8.CGLIB$builder$6() line: not available	
                                                                                                                GroovyReturnsSubclassTests$MyConfig$$EnhancerByCGLIB$$3aca3be8$$FastClassByCGLIB$$2a4c4776.invoke(int, Object, Object[]) line: not available	
                        MethodProxy.invokeSuper(Object, Object[]) line: 228	
                                                                                ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(Object, Method, Object[], MethodProxy) line: 285	
                                                                GroovyReturnsSubclassTests$MyConfig$$EnhancerByCGLIB$$3aca3be8.builder() line: not available	
                                                                NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]	
                            NativeMethodAccessorImpl.invoke(Object, Object[]) line: 57	
                                DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43	
            Method.invoke(Object, Object...) line: 601	
                                                                                                                                CglibSubclassingInstantiationStrategy(SimpleInstantiationStrategy).instantiate(RootBeanDefinition, String, BeanFactory, Object, Method, Object[]) line: 160	
                                                                    ConstructorResolver.instantiateUsingFactoryMethod(String, RootBeanDefinition, Object[]) line: 570	
                                                                                                                DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).instantiateUsingFactoryMethod(String, RootBeanDefinition, Object[]) line: 1029	
                                                                                                    DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBeanInstance(String, RootBeanDefinition, Object[]) line: 925	
                                                                                                DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).doCreateBean(String, RootBeanDefinition, Object[]) line: 490	
                                                                                            DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBean(String, RootBeanDefinition, Object[]) line: 461	
                AbstractBeanFactory$1.getObject() line: 295	
                                                                        DefaultListableBeanFactory(DefaultSingletonBeanRegistry).getSingleton(String, ObjectFactory) line: 223	
                                                                            DefaultListableBeanFactory(AbstractBeanFactory).doGetBean(String, Class<T>, Object[], boolean) line: 292	
                                            DefaultListableBeanFactory(AbstractBeanFactory).getBean(String) line: 194	
                                    DefaultListableBeanFactory.preInstantiateSingletons() line: 626	
                                                                                                            AnnotationConfigApplicationContext(AbstractApplicationContext).finishBeanFactoryInitialization(ConfigurableListableBeanFactory) line: 932	
                                                    AnnotationConfigApplicationContext(AbstractApplicationContext).refresh() line: 479	
                                    AnnotationConfigApplicationContext.<init>(Class<?>...) line: 73	
                                                                        NativeConstructorAccessorImpl.newInstance0(Constructor, Object[]) line: not available [native method]	
                                NativeConstructorAccessorImpl.newInstance(Object[]) line: 57	
                                    DelegatingConstructorAccessorImpl.newInstance(Object[]) line: 45	
                    Constructor<T>.newInstance(Object...) line: 525	
                CachedConstructor.invoke(Object[]) line: 77	
                            CachedConstructor.doConstructorInvoke(Object[]) line: 71	
                            ConstructorSite.callConstructor(Object, Object[]) line: 42	
                                            CallSiteArray.defaultCallConstructor(CallSite, Object, Object[]) line: 54	
                                AbstractCallSite.callConstructor(Object, Object[]) line: 182	
                            AbstractCallSite.callConstructor(Object, Object) line: 190	
                        GroovyReturnsSubclassTests.returnsSubclass() line: 16	
                                                                NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]	
                            NativeMethodAccessorImpl.invoke(Object, Object[]) line: 57	
                                DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43	
            Method.invoke(Object, Object...) line: 601	
                FrameworkMethod$1.runReflectiveCall() line: 44	
                        FrameworkMethod$1(ReflectiveCallable).run() line: 15	
                                FrameworkMethod.invokeExplosively(Object, Object...) line: 41	
    InvokeMethod.evaluate() line: 20	
                                        BlockJUnit4ClassRunner.runChild(FrameworkMethod, RunNotifier) line: 76	
                                BlockJUnit4ClassRunner.runChild(Object, RunNotifier) line: 50	
ParentRunner$3.run() line: 193	
            ParentRunner$1.schedule(Runnable) line: 52	
                                            BlockJUnit4ClassRunner(ParentRunner<T>).runChildren(RunNotifier) line: 191	
                                ParentRunner<T>.access$000(ParentRunner, RunNotifier) line: 42	
        ParentRunner$2.evaluate() line: 184	
                                    BlockJUnit4ClassRunner(ParentRunner<T>).run(RunNotifier) line: 236	
                                            JUnit4TestClassReference(JUnit4TestReference).run(TestExecution) line: 50	
                TestExecution.run(ITestReference[]) line: 38	
                                        RemoteTestRunner.runTests(String[], String, TestExecution) line: 467	
                    RemoteTestRunner.runTests(TestExecution) line: 683	
    RemoteTestRunner.run() line: 390	
            RemoteTestRunner.main(String[]) line: 197	

Notice that the following two lines are invoked repeatedly:

...
ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(Object, Method, Object[], MethodProxy) line: 297
...
BeanMethodInterceptor.intercept(Object, Method, Object[], MethodProxy) line: 285
...
ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(Object, Method, Object[], MethodProxy) line: 297
...
BeanMethodInterceptor.intercept(Object, Method, Object[], MethodProxy) line: 285

This seems to occur when ConfigurationClassEnhancer$BeanMethodInterceptor.intercept has a value referring to the superclass for cglibMethodProxy instead of the current class value. For example the following Groovy code:

public class GroovyReturnsSubclassTests {
    private AnnotationConfigApplicationContext context;

    @Test
    public void returnsSubclass() {
        context = new AnnotationConfigApplicationContext(MyConfig.class);
    }

    @Configuration
    static class MyConfig extends BaseConfig {
        @Bean
        public String builder() throws Exception {
            return null;
        }
    }

    @Configuration
    static abstract class BaseConfig {
        public abstract Object builder() throws Exception;
    }
}

Will randomly produce the following values for cglibMethodProxy:

cglibMethodProxy	MethodProxy  (id=57)	
	createInfo	MethodProxy$CreateInfo  (id=88)	
	fastClassInfo	null	
	initLock	Object  (id=97)	
	sig1	Signature  (id=102)	
		desc	"()Ljava/lang/Object;" (id=115)	
		name	"builder" (id=74)	
	sig2	Signature  (id=106)	
		desc	"()Ljava/lang/Object;" (id=115)	
		name	"CGLIB$builder$0" (id=137)	

This causes an infinite recursion, but the following value for cglibMethodProxy works:

cglibMethodProxy	MethodProxy  (id=57)	
	createInfo	MethodProxy$CreateInfo  (id=88)	
	fastClassInfo	null	
	initLock	Object  (id=96)	
	sig1	Signature  (id=101)	
		desc	"()Ljava/lang/String;" (id=114)	
		name	"builder" (id=73)	
	sig2	Signature  (id=103)	
		desc	"()Ljava/lang/String;" (id=114)	
		name	"CGLIB$builder$6" (id=135)

Additional Notes:

  • It appears to only occur with Groovy. It does not seem to happen with Java
  • If builder() defines the same return type for the sublcass and parent it seems to work
  • Sometimes it works just fine sometimes it fails with the NoClassDefFoundError: FatalBeanException
  • A configuration like this might be usefult to do something like this:
    @Configuration
    static class MyConfig extends BaseConfig {
        @Bean
        public String builder() throws Exception {
            return null;
        }
    }

    @Configuration
    static abstract class BaseConfig {
        @Bean
        public UsesBuilder usesBuilder() {
            Object b = builder();
            return new UsesBuilder(b);
        }
        public abstract Object builder() throws Exception;
    }
  • I will post a complete project that demonstrates the issue in the comments

Affects: 3.2.1

Issue Links:

Referenced from: commits spring-attic/spring-framework-issues@bd98e51, spring-attic/spring-framework-issues@a0e257c

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)type: bugA general bug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions