Issue with Spring AOP and Final class throwing “Could not generate CGLIB subclass”

孤街浪徒 提交于 2021-01-28 21:04:00

问题


1) Below is the small project I have where I do want logging with SpringAOP. Using spring-aop-4.1.6.RELEASE.jar and below is LoggingAspect.java with few point cuts.

package com.myprj.aop.aspect;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggingAspect {
    private final Log log = LogFactory.getLog(getClass());

    @Before("logForAllMethods()") // after advice with name pointcut that declared as name logForAllMethods()
    public void beforeAdviceForAllMethods(JoinPoint jp) throws Throwable {
        Object clazz = jp.getTarget().getClass().getName();
        String methodName = jp.getSignature().getName();
        log.info("Before Entering to Class " + clazz + " With Method Name " + methodName);
        // getting method parameter name
        Object[] obj = jp.getArgs();
        for (Object o : obj) {
            if (o != null) {
                log.info("Parameter Name..." + o.toString());
            } else {
                log.info("");
            }
        }

    }

    @After("logForAllMethods()") // after advice with name pointcut that declared as name logForAllMethods()
    public void afterAdviceForAllMethods(JoinPoint jp) throws Throwable {
        Object clazz = jp.getTarget().getClass().getName();
        String methodName = jp.getSignature().getName();
        log.info("After Entring to Method " + methodName + " in Calss " + clazz);
    }

    @Pointcut("execution(public * *(..))")      // enable for all public methods
    public void logForAllMethods() {
    }
}

Also below is the sample Service and ServiceImpl classes I have

package com.myprj.aop.service;

public interface TransferService {

    void transfer(String accountA, String accountB, Long amount);

    Double checkBalance(String account);

    Long withdrawal(String account, Long amount);

    void diposite(String account, Long amount);
}


package com.myprj.aop.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service
public class TransferServiceImpl implements TransferService {

    @Autowired
    @Qualifier("finalClass")
    FinalClass finalClass;

    @Override
    public void transfer(String accountA, String accountB, Long amount) {
        System.out.println(amount + " Amount has been tranfered from " + accountA + " to " + accountB);
    }

    @Override
    public Double checkBalance(String account) {
        System.out.println("Available balance: 50000");
        finalClass.toString();
        return new Double(50000);
    }

    @Override
    public Long withdrawal(String account, Long amount) {
        System.out.println("Withdrawal amount: " + amount);
        finalClass.toString();
        return amount;
    }

    @Override
    public void diposite(String account, Long amount) {
        System.out.println(amount + " Amount has been diposited to " + account);
        finalClass.toString();
    }

}

Also, I have a Singleton class where few methods need to be invoked like below.

package com.myprj.aop.service;

public class FinalClass {

    private String constructorParam;

    private FinalClass(String param) {
        constructorParam = param;
    }

    @Override
    public String toString() {
        System.out.println(constructorParam);
        return constructorParam;
    }
}

Below is applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
    <context:component-scan base-package="com.myprj.aop.*" />       
    <bean id="finalClass" class="com.myprj.aop.service.FinalClass">
        <constructor-arg value="constructorArg"></constructor-arg>
    </bean>
    <aop:aspectj-autoproxy/>    
</beans>

Main class:

package com.myprj.aop.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.myprj.aop.config.AppConfig;
import com.myprj.aop.service.TransferService;


public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // ConfigurableApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        TransferService transferService = applicationContext.getBean(TransferService.class);
        transferService.transfer("accountA", "accountB", 50000l);
        transferService.checkBalance("accountA");
        transferService.diposite("accountA", 50000l);
        transferService.withdrawal("accountB", 40000l);
        //applicationContext.close();
    }

}

Get below error

WARNING: Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transferServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.myprj.aop.service.FinalClass com.myprj.aop.service.TransferServiceImpl.finalClass; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'finalClass' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.myprj.aop.service.FinalClass]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: No visible constructors in class com.myprj.aop.service.FinalClass
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at com.myprj.aop.test.Main.main(Main.java:19)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.myprj.aop.service.FinalClass com.myprj.aop.service.TransferServiceImpl.finalClass; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'finalClass' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.myprj.aop.service.FinalClass]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: No visible constructors in class com.myprj.aop.service.FinalClass
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
    ... 13 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'finalClass' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.myprj.aop.service.FinalClass]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: No visible constructors in class com.myprj.aop.service.FinalClass
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1120)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1044)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
    ... 15 more
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.myprj.aop.service.FinalClass]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: No visible constructors in class com.myprj.aop.service.FinalClass
    at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:212)
    at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:109)
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:447)
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:333)
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:293)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1579)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
    ... 24 more
Caused by: java.lang.IllegalArgumentException: No visible constructors in class com.myprj.aop.service.FinalClass
    at org.springframework.cglib.proxy.Enhancer.filterConstructors(Enhancer.java:531)
    at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:448)
    at org.springframework.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33)
    at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
    at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
    at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
    at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:317)
    at org.springframework.aop.framework.ObjenesisCglibAopProxy.createProxyClassAndInstance(ObjenesisCglibAopProxy.java:57)
    at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:202)
    ... 31 more

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transferServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.myprj.aop.service.FinalClass com.myprj.aop.service.TransferServiceImpl.finalClass; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'finalClass' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.myprj.aop.service.FinalClass]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: No visible constructors in class com.myprj.aop.service.FinalClass
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at com.myprj.aop.test.Main.main(Main.java:19)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.myprj.aop.service.FinalClass com.myprj.aop.service.TransferServiceImpl.finalClass; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'finalClass' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.myprj.aop.service.FinalClass]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: No visible constructors in class com.myprj.aop.service.FinalClass
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
    ... 13 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'finalClass' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.myprj.aop.service.FinalClass]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: No visible constructors in class com.myprj.aop.service.FinalClass
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1120)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1044)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
    ... 15 more
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.myprj.aop.service.FinalClass]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: No visible constructors in class com.myprj.aop.service.FinalClass
    at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:212)
    at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:109)
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:447)
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:333)
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:293)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1579)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
    ... 24 more
Caused by: java.lang.IllegalArgumentException: No visible constructors in class com.myprj.aop.service.FinalClass
    at org.springframework.cglib.proxy.Enhancer.filterConstructors(Enhancer.java:531)
    at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:448)
    at org.springframework.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33)
    at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
    at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
    at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
    at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:317)
    at org.springframework.aop.framework.ObjenesisCglibAopProxy.createProxyClassAndInstance(ObjenesisCglibAopProxy.java:57)
    at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:202)
    ... 31 more

The inject injection is failing. After googling, many have suggested setter based injection. But when singleton class is created more operations are done in actual code. Also as per below link, this has been fixed in Spring 4.0. What is wrong with my code?


回答1:


as your exception says itself

No visible constructors in class com.myprj.aop.service.FinalClass

change your private constructor to public.




回答2:


It tells you what the problem is: No visible constructors in class com.myprj.aop.service.FinalClass.

There is no way for spring to "guess" which static getInstance() method to call to instantiate the singleton.
You must provide a public empty c'tor for it.

If you use spring accross your application, you can define FinalClass as a singleton using the @Scope property.



来源:https://stackoverflow.com/questions/52811994/issue-with-spring-aop-and-final-class-throwing-could-not-generate-cglib-subclas

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!