Proxy 带有spring的CGLIB抛出IllegalAccessError

Proxy 带有spring的CGLIB抛出IllegalAccessError,proxy,weblogic,spring-aop,oc4j,cglib,Proxy,Weblogic,Spring Aop,Oc4j,Cglib,我有一个spring应用程序,使用cglib代理启用aop进行日志记录: <?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:aop="http://www.springframework.org/schema/aop

我有一个spring应用程序,使用cglib代理启用aop进行日志记录:

<?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: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/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<aop:aspectj-autoproxy proxy-target-class="true"/>

<bean id="loggingPointcuts" class="com.coverall.integration.commons.logging.LoggingPointcuts"/>

<bean id="loggingAspect" class="com.coverall.integration.commons.logging.LoggingAspect"/>
</beans>

我不确定OC4J,但我们在JBoss6上遇到了完全相同的错误

通常,CGLIB可以增强包私有的(代理)类。正如您所观察到的,这在Jetty&Tomcat上运行良好。但是,它在默认的JBoss 6类加载器设置中不起作用

问题基本上是Spring指示CGLIB使用与目标类(超类,
com.company.int.components.core.registration.ComponentRegistryImpl$$enhancerbyglib$$730712da
)不同的类加载器创建代理类(子类,
com.company.int.components.core.registration.ComponentRegistryImpl
). 因此,虽然这些类在同一个文本包中,但它们实际上在运行时在不同的包中创建(因为它们在不同的类加载器中)

CGLIB默认在与代理目标相同的类加载器中定义代理类。但是,Spring会覆盖CGLIB增强器使用的类加载器。从
org.springframework.aop.framework.cglib2aoproxy.getProxy(ClassLoader)

//配置CGLIB增强器。。。
Enhancer Enhancer=createEnhancer();
if(类加载器!=null){
setClassLoader(classLoader);
智能类加载器的if(类加载器实例)&&
((SmartClassLoader)classLoader.isClassReloadable(ProxySuberclass)){
增强子setUseCache(false);
}
}
跟踪该类加载器的数据流显示它来自BeanFactory本身上定义的类加载器,默认为
Thread.currentThread().getContextClassLoader()
(在
org.springframework.util.ClassUtils.getDefaultClassLoader()

在健全的servlet容器(如Jetty和Tomcat)中,上下文类加载器与加载所有应用程序类(在WEB-INF/lib或WEB-INF/classes中)的类加载器相同。然而,在JBoss6(我猜是OC4J)中,这两个是不同的。上下文类加载器实际上是webapp类加载器的子类。它实际上没有定义类,只是将所有事情委托给父级。在JBoss中,上下文类加载器是
WebCtxLoader$ENCLoader
)的一个实例

我们使用的解决方法是覆盖
WebApplicationContext
BeanFactory
)的类加载器,以便使用“真正的”webapp类加载器。我们通过创建自己的
ContextLoaderListener
(加载MyContextLoaderListener实现本身的类加载器就是我们想要的):

公共类MyContextLoaderListener扩展了ContextLoaderListener{
@凌驾
受保护的void customizeContext(ServletContext ServletContext,ConfigurableWebApplicationContext applicationContext){
ClassLoader ClassLoader=getClass().getClassLoader();
debug(“将WebApplicationContext类加载器从%s重写为%s”,applicationContext.getClassLoader(),classloader);
((DefaultResourceLoader)applicationContext).setClassLoader(classLoader);
}
}
您需要在
web.xml
中添加类作为上下文侦听器:


com.company.MyContextLoaderListener

谢谢Eric,这对我很有用。我们还决定从OC4J转向Weblogic,因为对OC4J的支持已经停止。希望我在weblogic上不需要这种解决方法:)我们最终在weblogic上部署了我们的应用程序,并遇到了相同的问题(以前在OC4J上看到过)。我使用了这个解决方案,它成功了!再次感谢:)
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.company.int.components.core.registration.ComponentRegistryImpl]: Common causes of this problem include using a final class or a non-visible class; nested exception is net.sf.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
    at org.springframework.aop.framework.Cglib2AopProxy.getProxy(Cglib2AopProxy.java:207) ~[org.springframework.aop-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:112) ~[org.springframework.aop-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:476) ~[org.springframework.aop-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:362) ~[org.springframework.aop-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:322) ~[org.springframework.aop-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:407) [org.springframework.beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1461) [org.springframework.beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) [org.springframework.beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    ... 40 common frames omitted
Caused by: net.sf.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
    at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:237) ~[cglib-nodep-2.2.2.jar:na]
    at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377) ~[cglib-nodep-2.2.2.jar:na]
    at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:285) ~[cglib-nodep-2.2.2.jar:na]
    at org.springframework.aop.framework.Cglib2AopProxy.getProxy(Cglib2AopProxy.java:201) ~[org.springframework.aop-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    ... 47 common frames omitted
Caused by: java.lang.reflect.InvocationTargetException: null
    at sun.reflect.GeneratedMethodAccessor12.invoke(Unknown Source) ~[na:na]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[na:1.6.0_20]
    at java.lang.reflect.Method.invoke(Method.java:597) ~[na:1.6.0_20]
    at net.sf.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:384) ~[cglib-nodep-2.2.2.jar:na]
    at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:219) ~[cglib-nodep-2.2.2.jar:na]
    ... 50 common frames omitted
Caused by: java.lang.IllegalAccessError: class com.company.int.components.core.registration.ComponentRegistryImpl$$EnhancerByCGLIB$$730712da cannot access its superclass com.company.int.components.core.registration.ComponentRegistryImpl
    at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.6.0_20]
    at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632) ~[na:1.6.0_20]
    at java.lang.ClassLoader.defineClass(ClassLoader.java:616) ~[na:1.6.0_20]
    ... 55 common frames omitted
<listener>
    <listener-class>com.company.MyContextLoaderListener</listener-class>
</listener>