Spring (Error creating bean, No visible constructors) for Singleton class with private constructor

10,592

The problem is not the bean creation itself (as you already noticed, that's not different from the other beans). The issue seems to be related to some AOP configuration that you're trying to use. If you want to create a proxy for that class, it cannot do it with CGLIB because the class cannot be subclassed (since it has a private constructor).

The only way to get around this (given your current design) is to create an interface that will be implemented by the ApplicationConfiguration class and then create the proxy for that interface instead of proxy-ing the class.

Share:
10,592
likeToCode
Author by

likeToCode

I like programming

Updated on July 17, 2022

Comments

  • likeToCode
    likeToCode almost 2 years

    I have 4 singleton classes with private constructors and I'm trying to create bean property for all the 4 classes.

    The main problem is, I'm able to create the bean for 3 classes and these 3 classes have similar structure with a getInstance method and a private constructor() (Singleton class) but the fourth and the last one is throwing an exception (Exception message is pasted below)

    Please find below the getInstance method, the private constructor and the bean id declaration. Which is same across all the four bean declarations

    But If I change the constructor from "Private" to "Public" then I dont get the error. Could anyone throw any light on what is happening? Since the other three classes have private constructors and they work perfectly fine

    The getInstance() method

    public static ApplicationConfiguration getInstance() throws IOException,
                IllegalArgumentException, InconsistentDataException {
            ApplicationConfiguration result = instance.get();
            if (result == null) {
                try {
                    // Check again if already created
                    result = instance.get();
                    if (result == null) {
                        result = new ApplicationConfiguration();
    
                    }
                } finally {
                    // something here
                }
            } 
            return result;
        }
    

    The private constructor

    private ApplicationConfiguration() throws Exception {
            // call a method here
        }
    

    The bean property declaration

    <bean id="configManager" class="com.manager.ApplicationConfiguration" factory-method="getInstance" />
    
    <bean id="configEnricher" class="com.enricher.ApplicationConfiguration" factory-method="getInstance" />
    
    <bean id="configBussiness" class="com.validationservice.ApplicationConfiguration" factory-method="getInstance" />
    

    The above three works

    This bean property is throwing the error

    <bean id="configEviction" class="com.evictionservice.ApplicationConfiguration" factory-method="getInstance" />
    

    The Exception message

    [#|2012-08-07 11:53:21,130|ERROR|RMI TCP Connection(226)-172.18.36.14|org.springframework.
    web.context.ContextLoader||slodev-rhngp5.mblox.com|core-1|Context initialization failed|#]
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'co
    nfigEviction' defined in ServletContext resource [/WEB-INF/camel-context.xml]: Initializat
    ion of bean failed; nested exception is org.springframework.aop.framework.AopConfigExcepti
    on: Could not generate CGLIB subclass of class [class com.evictionservice.ApplicationConfiguration]: 
    Common causes of this problem include using
    a final class or a non-visible class; nested exception is java.lang.IllegalArgumentExcepti
    on: No visible constructors in class com.evictionservice.ApplicationConfiguration
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.do
    CreateBean(AbstractAutowireCapableBeanFactory.java:526)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.cr
    eateBean(AbstractAutowireCapableBeanFactory.java:455)
            at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(Abstr
    actBeanFactory.java:293)
            at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingl
    eton(DefaultSingletonBeanRegistry.java:222)
            at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(Abstrac
    tBeanFactory.java:290)
            at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractB
    eanFactory.java:192)
            at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstant
    iateSingletons(DefaultListableBeanFactory.java:585)
            at org.springframework.context.support.AbstractApplicationContext.finishBeanFactor
    yInitialization(AbstractApplicationContext.java:895)
            at org.springframework.context.support.AbstractApplicationContext.refresh(Abstract
    ApplicationContext.java:425)
    :