Announcement Announcement Module
Collapse
No announcement yet.
CGLIB Proxy, no default constructor Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • CGLIB Proxy, no default constructor

    Hi,

    I'm trying to proxy a concrete class (com.company.Concrete) which only as a one-argument constructor.

    ApplicationContext
    Code:
            <aop:aspectj-autoproxy proxy-target-class="true" />
    	<bean id="concrete" class="com.company.Concrete" scope="prototype" />
    Initialization code (try 1):
    Code:
            Object args = ... 
            // throws exception
            Concrete c = (Concrete) applicationContext.getBean("concrete", args);
    Initialization code (try 2):
    Code:
           Object args = ... 
           // Also throws exception
           Concrete concrete = (Concrete) applicationContext.getAutowireCapableBeanFactory().initializeBean(
                 new Concrete(args), "concrete");
    Exception
    Code:
    rg.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.company.Concrete]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
    	at org.springframework.aop.framework.Cglib2AopProxy.getProxy(Cglib2AopProxy.java:212)
    	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:1418)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    	... 10 more
    Caused by: java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
    	at net.sf.cglib.proxy.Enhancer.emitConstructors(Enhancer.java:721)
    	at net.sf.cglib.proxy.Enhancer.generateClass(Enhancer.java:499)
    	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:200)
    	... 17 more

    I don't see why this should be a problem.
    I'm using GenericApplicationContext which invokes getBean() with the necessary constructor arguments. Shouldn't spring delegate to the appropriate CGLIB method (which does take constructor arguments) ?


    Note, I've also tried using a private default constructor with no success.



    Regards,
    Johan
    Last edited by Toxic; Mar 13th, 2011, 08:33 AM.

  • #2
    It has nothing to do with spring. CGLib creates a subclass for class proxying and due to that it requires a no-argument constructor to be available.

    Comment


    • #3
      Thanks for your reply. What about Enhancer.create(java.lang.Class[], java.lang.Object[]) ?

      Comment


      • #4
        I'm having the same issue. I found code that uses that Enhancer method that Toxic mentions.

        Cglib2AopProxy has a method

        Code:
        public void setConstructorArguments(Object[] constructorArgs, Class[] constructorArgTypes)
        but it is not called anywhere in spring that I(ntelliJ) can find. If it were called, then it seems like Spring could handle objects without no-arg constructors since there's this, in the same class:

        Code:
        public Object getProxy(ClassLoader classLoader) {
        {snip}
        
        
        // Generate the proxy class and create a proxy instance.
            Object proxy;
            if (this.constructorArgs != null) {
                proxy = enhancer.create(this.constructorArgTypes, this.constructorArgs);
            }
            else {
                proxy = enhancer.create();
            }
        
            return proxy;
        }
        This is using Spring 3.0.6 with cglib 2.2.2.

        Comment

        Working...
        X