简体   繁体   English

AspectJExpressionPointcut使用错误的classLoader

[英]AspectJExpressionPointcut uses wrong classLoader

I have a Java EE application consisting of multiple OSGi bundles running within Apache Felix container. 我有一个Java EE应用程序,该应用程序由在Apache Felix容器中运行的多个OSGi捆绑软件组成。 One of these bundles is responsible for loading Spring application context. 这些捆绑包之一负责加载Spring应用程序上下文。 I'm using Spring AOP in my application and the following error arised in my bundle: 我在应用程序中使用Spring AOP,并且捆绑中出现以下错误:

java.lang.IllegalArgumentException: warning no match for this type name: com.somepackage.SomeClass [Xlint:invalidAbsoluteTypeName]
at org.aspectj.weaver.tools.PointcutParser.parsePointcutExpression(PointcutParser.java:301)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:206)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.checkReadyToMatch(AspectJExpressionPointcut.java:192)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.getClassFilter(AspectJExpressionPointcut.java:169)
at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:208)
at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:262)
at org.springframework.aop.support.AopUtils.findAdvisorsThatCanApply(AopUtils.java:294)
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findAdvisorsThatCanApply(AbstractAdvisorAutoProxyCreator.java:118)
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(AbstractAdvisorAutoProxyCreator.java:88)
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean(AbstractAdvisorAutoProxyCreator.java:69)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:330)
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:1573)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:540)

The cause of this problem is that class(com.somepackage.SomeClass) used in pointcat of my aspect was loaded by bundle ClassLoader but AspectJExpressionPointcut passes default ClassLoader to buildPointcutExpression() method: 导致此问题的原因是,我的方面的Pointcat中使用的类(com.somepackage.SomeClass)由捆绑包ClassLoader加载,但是AspectJExpressionPointcut将默认的ClassLoader传递给buildPointcutExpression()方法:

private void checkReadyToMatch() {
    if (getExpression() == null) {
        throw new IllegalStateException("Must set property 'expression' before attempting to match");
    }
    if (this.pointcutExpression == null) {
        this.pointcutClassLoader = (this.beanFactory instanceof ConfigurableBeanFactory ?
                ((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader() :
                ClassUtils.getDefaultClassLoader());
        this.pointcutExpression = buildPointcutExpression(this.pointcutClassLoader);
    }
}

which knows nothing about this class (com.somepackage.SomeClass). 对此类一无所知(com.somepackage.SomeClass)。

The problem was solved by changing ClassLoader in thread initializing Spring Application Context: 通过在初始化Spring Application Context的线程中更改ClassLoader解决了该问题:

Thread.currentThread().setContextClassLoader(bundleClassLoader);

So method ClassUtils.getDefaultClassLoader() returns bundleClassLoader which can load class mentioned in pointcut. 因此,方法ClassUtils.getDefaultClassLoader()返回bundleClassLoader,它可以加载切入点中提到的类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM