我不确定是否有解决您问题的简便方法。正如我说过的,我以前从未与AspectJ合作过,但我相信这是织布人的不当行为。
问题描述:
在引导过程中,代理会尝试申请其他编织不仅对
WebAppClassLoader,但是对整体的类加载器链(一旦每一个classloader)即:
sun.misc.Launcher$AppClassLoader,
sun.misc.Launcher$ExtClassLoader,
org.apache.catalina.loader.StandardClassLoader(tomcat的的类加载器)。当您使用该
meta-INF/aop.xml方法时,由于“配置文件不可用”,它会禁用上述类加载器的编织(如果启用
verbose模式,您可以在控制台中看到这些消息)。使用文件配置方法时,
链中的所有类加载器都可以 使用配置。由于它确实找到了配置文件,因此代理会解析定义,因此不会找到方面的类并显示错误。
奇怪的是,如配置文档中所述,如果您使用
WeavingURLClassLoader加载时间编织方法, “
…它还允许用户通过类加载器显式限制可以编织哪些类”
。因此,这实际上是类加载器方法可以具有的功能(!),而代理程序方法则没有。(很遗憾,我无法使用此方法)
好消息 (好消息 ):
好消息是,您可以轻松创建自己的代理,而忽略上述类加载器的编织。坏消息是,仅限制按类加载器进行编织是不够的,因为如果在同一服务器上有其他应用程序,则Tomcat仍将使用
WebAppClassLoader加载它们,因此您仍会收到这些应用程序的错误消息。(在这种情况下,也许您可以扩展下面的类来过滤包/类)。
在下面可以找到修改后的代理的两个类。要使用它们,您需要执行以下操作:
- 解压缩
aspectjweaver.jar
到文件夹 - 在“
org/aspectj/weaver/loadtime
创建一个新文件夹filter
以匹配程序包名称”下,在编译它们之后将两个新类放在其中。 - 编辑
meta-INF/MANIFEST.MF
文件并更改行
Premain-Class: org.aspectj.weaver.loadtime.Agent至
Premain-Class: org.aspectj.weaver.loadtime.filter.FilterAgent
重新打包,您就可以准备好新的代理了。
启动JVM时,您现在可以传递一个新的系统属性,该属性带有一个用逗号分隔的类加载器列表,您想忽略它们
-Dorg.aspectj.weaver.loadtime.filter=sun.misc.Launcher$AppClassLoader,sun.misc.Launcher$ExtClassLoader,org.apache.catalina.loader.StandardClassLoader
(即,我已经设置CATALINA_OPTS
好了)。
这些类是原始代理的类
Agent和的修改后的副本
ClassPreProcessorAgentAdapter。我添加的唯一代码是解析上述系统属性(如果存在)并忽略对我们不感兴趣的类加载器的调用的部分。
使用后果自负:)希望对您有所帮助
package org.aspectj.weaver.loadtime.filter;import java.lang.instrument.ClassFileTransformer;import java.lang.instrument.Instrumentation;public class FilterAgent { private static Instrumentation s_instrumentation; // Use our own version of ClassFileTransformer that would filter out selected classloaders private static ClassFileTransformer s_transformer = new ClassPreprocessorFilteredAdapter(); public static void premain(String options, Instrumentation instrumentation) { if (s_instrumentation != null) { return; } s_instrumentation = instrumentation; s_instrumentation.addTransformer(s_transformer); } public static Instrumentation getInstrumentation() { if (s_instrumentation == null) { throw new UnsupportedOperationException("Java 5 was not started with preMain -javaagent for AspectJ"); } return s_instrumentation; }}//-----------------------------------------------------------------------------------package org.aspectj.weaver.loadtime.filter;import java.lang.instrument.ClassFileTransformer;import java.lang.instrument.IllegalClassFormatException;import java.security.ProtectionDomain;import java.util.HashMap;import java.util.Map;import org.aspectj.weaver.loadtime.Aj;import org.aspectj.weaver.loadtime.ClassPreProcessor;public class ClassPreprocessorFilteredAdapter implements ClassFileTransformer { private static ClassPreProcessor s_preProcessor; private static Map<String, String> ignoredClassloaderNames = new HashMap<String, String>(); static { try { s_preProcessor = new Aj(); s_preProcessor.initialize(); String ignoredLoaders = System.getProperty("org.aspectj.weaver.loadtime.filter", ""); if (ignoredLoaders.length() > 0) { String[] loaders = ignoredLoaders.split(","); for (String s : loaders) { s = s.trim(); ignoredClassloaderNames.put(s, s); System.out.println("---> Will filtered out classloader: " + s); } } } catch (Exception e) { throw new ExceptionInInitializerError("could not initialize JSR163 preprocessor due to: " + e.toString()); } } @Override public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] bytes) throws IllegalClassFormatException { if (classBeingRedefined != null) { System.err.println("INFO: (Enh120375): AspectJ attempting reweave of '" + className + "'"); } String loaderName = loader.getClass().getName(); if (shouldIgnoreClassLoader(loaderName)) { return bytes; } return s_preProcessor.preProcess(className, bytes, loader, protectionDomain); } private boolean shouldIgnoreClassLoader(String loaderName) { boolean result = false; String ignoredLoader = ignoredClassloaderNames.get(loaderName); if (ignoredLoader != null) { result = true; // if the loader name exists in the map we will ignore weaving } return result; }}


