AspectJ autoproxy 在 GigaSpaces 8 和 Spring 3 上失败,因为 class 是由不同的 classloader 加载的

AspectJ autoproxy fails with GigaSpaces 8 and Spring 3 because class is loaded by different classloader

我们使用的是 GigaSpaces 版本 8.0.0(是的,它很旧)以及 Spring 3(是的,它也很旧)。有两个模块A和B,A是"main"模块,读写space,暴露一些远程服务。 A和B运行分别。 B 创建一个实体的实例,该实体的字段是 class 对象。这个class只存在于B; A对此一无所知。然后它对 A 进行远程调用,最终将实例写入 space.

稍后,A 加载此实体并通过执行 entity.getClassObject().newInstance() 创建远程 class 的实例。即使这个 class 在 A 的 运行time classloader 中不存在,这仍然有效,因为这个 class 的 classloader 是 LRMI(light远程方法调用)class GigaSpaces 附带的加载程序。我想它知道如何实例化它。

当我们向 A 添加方面时出现了问题。我们有现有代码使用 A 的应用程序上下文自动装配远程实例 class 并使用 initializeBean 初始化它。在我们添加方面之前,自动装配和初始化工作正常。现在,在初始化期间,它会尝试查看方面中的建议是否适用于正在初始化的 bean。作为此过程的一部分,它尝试使用 Class.forName 和 bean 的 class' 名称创建 class 的实例。这导致 ClassNotFoundException 因为 class 显然不存在于 运行time class 加载程序中。所以 AspectJ 将类型解析为 MissingResolvedTypeWithKnownSignature 而不是立即失败。但最终当 AspectJ 试图找到 class 的 superclass 时会失败,因为它没有该信息,并抛出以下异常:

org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException: warning can't determine implemented interfaces of missing type com.mypackage.MyRemoteClass
 [Xlint:cantFindType]
        at org.aspectj.weaver.reflect.ReflectionWorld$ExceptionBasedMessageHandler.handleMessage(ReflectionWorld.java:129)
        at org.aspectj.weaver.Lint$Kind.signal(Lint.java:328)
        at org.aspectj.weaver.MissingResolvedTypeWithKnownSignature.raiseCantFindType(MissingResolvedTypeWithKnownSignature.java:232)
        at org.aspectj.weaver.MissingResolvedTypeWithKnownSignature.getDeclaredInterfaces(MissingResolvedTypeWithKnownSignature.java:86)
        at org.aspectj.weaver.ResolvedType.getDirectSupertypes(ResolvedType.java:82)
        at org.aspectj.weaver.patterns.TypePattern.matchesSubtypes(TypePattern.java:178)
        at org.aspectj.weaver.patterns.ExactTypePattern.matchesSubtypes(ExactTypePattern.java:74)
        at org.aspectj.weaver.patterns.TypePattern.matchesStatically(TypePattern.java:130)
        at org.aspectj.weaver.patterns.KindedPointcut.fastMatch(KindedPointcut.java:141)
        at org.aspectj.weaver.internal.tools.PointcutExpressionImpl.couldMatchJoinPointsInType(PointcutExpressionImpl.java:84)
        at org.springframework.aop.aspectj.AspectJExpressionPointcut.matches(AspectJExpressionPointcut.java:238)
        at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:200)
        at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:254)
        at org.springframework.aop.support.AopUtils.findAdvisorsThatCanApply(AopUtils.java:286)
        at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findAdvisorsThatCanApply(AbstractAdvisorAutoProxyCreator.java:117)
        at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(AbstractAdvisorAutoProxyCreator.java:87)
        at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean(AbstractAdvisorAutoProxyCreator.java:68)
        at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:359)
        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:1426)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:386)
...

有什么办法解决这个问题吗?我可以想到两种方法,但我不确定如何去做。一种是以某种方式阻止 Spring 检查方面是否适用,另一种可能是将 运行time classloader 换成委托给 LRMI classloader 如果它在 运行 时间 class 加载程序中找不到 class。但我不确定我是否可以获得 LRMI classloader.

的实例

有人 运行 遇到过这类问题吗?

这是我使用的 AspectJ 版本 (1.6.12) 中的 known issue。它似乎已在更高版本中得到修复——至少从 1.8.14 开始(这是我将其升级到的版本)。所以升级我的 AspectJ 版本解决了这个问题。