Announcement Announcement Module
Collapse
No announcement yet.
upgrade from 2.0-M5 to 2.0: cannot subclass final proxy Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • upgrade from 2.0-M5 to 2.0: cannot subclass final proxy

    I upgraded from 2.0-M5 to 2.0 and now have some problems deploying my application on the webserver. It's a webapp using acegi security and transactions which seem to be co-operating badly now.

    The way it is configured now, all the service beans are proxied twice and CGLib is complaining that the first proxy is final and is not allowing it to create the second proxy. (See the stacktrace below.)

    It seems in the previous Spring release M5, BeanNameAutoProxyCreator for Acegi and aspectj-autoproxy were co-existing fine. The transactionality is catered for first using annotations and aspectj, and acegi is implemented using BeanNameAutoProxyCreator.

    My first question is, can you confirm that this change is expected? Do you know about this and is there an immediate work-around? If you could confirm that for the sake of my sanity and to reassure me that I haven't just mangled my Jar dependencies, I'd be grateful.

    Secondly, what course to take? I want to change the config anyway to avoid proxying the service beans twice, and I want to get rid of the annotations that are putting undesired dependencies in the service classes. I am using interfaces but the stacktrace shows CGLib is active - is there a simple, elegant approach that doesn't involve CGLib?

    Here's the stack trace:

    Code:
    ERROR web.context.ContextLoader.initWebApplicationContext() <Context initialization failed>
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'securityServices' defined in class path resource [applicationContext.xml]: 
    Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: 
    Couldn't generate CGLIB subclass of class [class $Proxy8]: 
    Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot
     subclass final class class $Proxy8
    Caused by:
    org.springframework.aop.framework.AopConfigException: 
    Couldn't generate CGLIB subclass of class [class $Proxy8]: 
    Common causes of this problem include using a final class or a non-visible class; 
    nested exception is java.lang.IllegalArgumentException: 
    Cannot subclass final class class $Proxy8
    Caused by:
    java.lang.IllegalArgumentException: Cannot subclass final class class $Proxy8
            at net.sf.cglib.proxy.Enhancer.generateClass(Enhancer.java:446)
            at net.sf.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33)
            at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
            at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
            at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
            at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:285)
            at org.springframework.aop.framework.Cglib2AopProxy.getProxy(Cglib2AopProxy.java:202)
            at org.springframework.aop.framework.Cglib2AopProxy.getProxy(Cglib2AopProxy.java:147)
            at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:72)
            at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:392)
            at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:249)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBea
    nFactory.java:311)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1038)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:420)
            at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:245)
            at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:141)
            at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:242)
            at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:156)
            at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:290)
            at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:348)
            at org.springframework.web.context.support.AbstractRefreshableWebApplicationContext.refresh(AbstractRefreshableWebApplicationContext.java:156)
            at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:246)
            at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:184)
            at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:49)
            at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3729)
            at org.apache.catalina.core.StandardContext.start(StandardContext.java:4187)

  • #2
    There was a bug in 2.0 to do with auto-proxying, where double proxying was the result. You may be affected by that. I'm not sure how much of auto-proxying was involved, but I know that BeanNameAutoProxyCreator was definitely part of the problem.

    If this is the bug that has caused your problem then it is possible that Spring is trying to use Cglib to proxy a JDK Proxy, which itself was already created for your interface, as you wanted.

    I understand that the bug is fixed in the latest builds (and in 2.0.1). A workaround if you can't wait is to extend BeanNameAutoProxyCreator and override postProcessBeforeInstantiation, checking for an existing proxy with AopUtils.isAopProxy() and only calling the superclass method if it is false.
    Last edited by Dave Syer; Oct 25th, 2006, 05:07 AM.

    Comment


    • #3
      Thanks for the info. I think your assumption is right. I have reconfigured my transactions to use BeanNameAutoProxyCreator, instead of using the annotations method with AspectJ, and then listing the different interceptors so that I only have one proxy. (That does mean only one is created, right?)

      Comment

      Working...
      X