javaspringaspectjcglibload-time-weaving

Spring: Is CGLIB required for injection of a concrete class using @Resource


I have configured Spring 3.0.6 with AspectJ LTW using spring-instrument.jar and:

<context:load-time-weaver aspectj-weaving="on" weaver-class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />

When removing CGLIB from dependencies, I'm getting the following exception even after MyBean is created (and its @PostConstruct is run):

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'crawlItemService' defined in file [/path/to/project/foo/bar/MyBean.class]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:435)
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:409)
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:541)
    at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:147)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:297)
    ... 72 more
Caused by: org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.
    at org.springframework.aop.framework.DefaultAopProxyFactory.createAopProxy(DefaultAopProxyFactory.java:67)
    at org.springframework.aop.framework.ProxyCreatorSupport.createAopProxy(ProxyCreatorSupport.java:104)
    at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:112)
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:476)
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:362)
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:322)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:407)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1426)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    ... 83 more

Does it mean that I should have CGLIB even in existence of a load time weaver?


Solution

  • After over 3 hours of investigations of the code and changing Spring bean definition XMLs, I finally found the problem. This could be found from this part of stacktrace, which I noticed after finding the solution:

    at org.springframework.scheduling.annotation.AsyncAnnotationBeanPostProcessor.postProcessAfterInitialization(AsyncAnnotationBeanPostProcessor.java:126)
    

    Based on the note here, I changed all proxy-target-class attributes to false in <aop:config>, <aop:aspectj-autoproxy>, and <tx:annotation-driven>, but to no success.

    Then I started removing parts of my XML definition to find which one fixes this problem. Commenting <task:annotation-driven> helped and the problem resolved. I then saw that this element has a mode attribute which I didn't specified, so its default value, proxy, is used, and so CGLIB is required. As I changed mode="aspectj" the problem resolved:

    <task:annotation-driven scheduler="dataProviderScheduler" executor="dataProviderExecutor" mode="aspectj" />