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?
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