Search code examples
javaspringconfigurationjava-7spring-annotations

Stackoverflow error in Spring's (3.2.0) ConfigurationClassEnhancer after upgrading to Java 7


We have a couple of @Configuration annotated classes, the application is working fine on sun-jdk-6,but after upgrading to oracle-jdk-7 a SO error happens.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cacheManagerPeerProviderFactory' defined in class path resource [com/egnyte/filestore/cache/CacheManagerPeerProviderConfigurationProvider.class]: Instantiation of bean failed; nested exception is 
org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public java.lang.Object com.egnyte.filestore.cache.CacheManagerPeerProviderConfigurationProvider.get()] threw exception; nested exception is java.lang.StackOverflowError
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:181)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:570)
    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.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:297)
    at com.egnyte.filestore.cache.CacheManagerPeerProviderConfigurationProvider$$EnhancerByCGLIB$$6b65bac9.get(<generated>)
    at com.egnyte.filestore.cache.CacheManagerPeerProviderConfigurationProvider.get(CacheManagerPeerProviderConfigurationProvider.java:22)
    at com.egnyte.filestore.cache.CacheManagerPeerProviderConfigurationProvider$$EnhancerByCGLIB$$6b65bac9.CGLIB$get$0(<generated>)
    at com.egnyte.filestore.cache.CacheManagerPeerProviderConfigurationProvider$$EnhancerByCGLIB$$6b65bac9$$FastClassByCGLIB$$1a8904d5.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:285)
    at com.egnyte.filestore.cache.CacheManagerPeerProviderConfigurationProvider$$EnhancerByCGLIB$$6b65bac9.get(<generated>)
    at sun.reflect.GeneratedMethodAccessor27.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
[SNAP...]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:160)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:570)
    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.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:297)
    at foo.bar.cache.CacheManagerPeerProviderConfigurationProvider$$EnhancerByCGLIB$$6b65bac9.get(<generated>)
    at foo.bar.cache.CacheManagerPeerProviderConfigurationProvider.get(CacheManagerPeerProviderConfigurationProvider.java:22)
    at foo.bar.cache.CacheManagerPeerProviderConfigurationProvider$$EnhancerByCGLIB$$6b65bac9.CGLIB$get$0(<generated>)
    at foo.bar.cache.CacheManagerPeerProviderConfigurationProvider$$EnhancerByCGLIB$$6b65bac9$$FastClassByCGLIB$$1a8904d5.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:285)
    at foo.bar.cache.CacheManagerPeerProviderConfigurationProvider$$EnhancerByCGLIB$$6b65bac9.get(<generated>)
    at sun.reflect.GeneratedMethodAccessor27.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:160)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:570)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1029)

Note that foo.bar.cache.CacheManagerPeerProviderConfigurationProvider.get(CacheManagerPeerProviderConfigurationProvider.java:22) points to a line of code with the @Configuration annotation, not the actual get() implementation.

Default proxy mode is "no". The class has nothing fancy:

@Configuration
class CacheManagerPeerProviderConfigurationProvider implements Provider<Foo<?>> { 

    @Inject
    private List<Pair<String, Integer>> peers;

    @Override
    @Bean(name = CACHE_MANAGER_PEER_PROVIDER_FACTORY)
    public Foo<?> get() { 
        return new Foo(peers);    
    }
}

Is this a bug in Spring? Is it possible to disable the enhancer?


Solution

  • OK, so this is definately a bug in Spring.

    To fix this remove the Provider<> interface, and therfore make the get() method a regular one and not overriden (it seems it's the Provider interface which is messing up internal Spring plumbing, not the method being an override per se). So much for making your dependencies jsr-330 compatibile.

    @Configuration
    class CacheManagerPeerProviderConfigurationProvider 
      //implements Provider<Foo<?>> 
        { 
    
        @Inject
        private List<Pair<String, Integer>> peers;
    
        //@Override
        @Bean(name = CACHE_MANAGER_PEER_PROVIDER_FACTORY)
        public Foo<?> get() { 
            return new Foo(peers);    
        }
    }
    

    Works!

    As an alternative solution change the @Configuration to @Component or @Named

    @Named
    class CacheManagerPeerProviderConfigurationProvider implements Provider<Foo<?>> 
        { 
    
        @Inject
        private List<Pair<String, Integer>> peers;
    
        @Override
        @Bean(name = CACHE_MANAGER_PEER_PROVIDER_FACTORY)
        public Foo<?> get() { 
            return new Foo(peers);    
        }
    }
    

    Resolved in SPR-11830