AspectJ 切入点不适用于外部类和 LTW

发布于 2024-12-07 04:24:01 字数 4210 浏览 0 评论 0原文

我正在尝试将 AspectJ (直到昨天我还不知道)与 LTW 一起使用,以了解 现有框架如何 有效。 简而言之,我对如何解析框架的输入 XML 文件感兴趣。

我编写了以下方面:

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.CodeSignature;

public aspect UnitContextTrace {

    static final void println(String s){ System.out.println(s); }

    pointcut unitContextMethodsExec(): call(public * org.ivalidator.framework.test.UnitContext.* (..)) ||
    call(public void org.ivalidator.repository..*.set* (..));

    Object around(): unitContextMethodsExec() {
        println("Intercepted message: " +
                thisJoinPointStaticPart.getSignature().getName());
        println("in class: " +
                thisJoinPointStaticPart.getSignature().getDeclaringType().getName());
        printParameters(thisJoinPoint);
        println("Running original method: \n" );
        Object result = proceed();
        println("  result: " + result );
        return result;
    }

    static private void printParameters(JoinPoint jp) {
        println("Arguments: " );
        Object[] args = jp.getArgs();
        String[] names = ((CodeSignature)jp.getSignature()).getParameterNames();
        Class[] types = ((CodeSignature)jp.getSignature()).getParameterTypes();
        for (int i = 0; i < args.length; i++) {
            println("  "  + i + ". " + names[i] +
                    " : " +            types[i].getName() +
                    " = " +            args[i]);
        }
    }
}

这应该调试对 UnitContext 接口实现的方法的调用以及对属于 org.ivalidator 的任何类的 setXXX() 方法的调用.repository.* 包。

我将 Aspect 打包在自己的 jar 中

 ajc UnitContextTrace.aj -outxml -outjar aspectTrace.jar -extdirs "C:\aspectj1.6\lib\"

,并启动了程序(我使用 ant 脚本),将 -javaagent:${aspectj.home}/lib/aspectjweaver.jar 传递到 JVM。

该方面的第一部分(UnitContext 方法)有效,我可以看到例如

拦截消息:getAdapter...

但不幸的是,没有调用 setXXX() 方法的日志。 org.ivalidator.repository.* 包是 ivalidator.jar 的一部分,它当然使用存储在 lib 文件夹中的第 3 方库。结构如下:

  • Ivalidator.jar
  • /lib
    • Castor-0.9.7.jar
    • xercesImpl.jar

使用调试器,我注意到 setXXX() 方法是从外部调用的类(属于 castor-0.9.7.jar,它们又由 xerces 的类调用)。更准确地说,我在调试器中看到的堆栈跟踪是这样的:

**ParameterXml.setName(String) line: 60 (I want to intercept this)**
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]  
NativeMethodAccessorImpl.invoke(Object, Object[]) line: not available   
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: not available   
Method.invoke(Object, Object...) line: not available    
FieldHandlerImpl.setValue(Object, Object) line: 501 
UnmarshalHandler.processAttribute(String, String, String, XMLFieldDescriptor, XMLClassDescriptor, Object) line: 3028    
UnmarshalHandler.processAttributes(AttributeSet, XMLClassDescriptor) line: 2702 
UnmarshalHandler.startElement(String, String, AttributeSet) line: 2325  
UnmarshalHandler.startElement(String, String, String, Attributes) line: 1388    
SAXParser(AbstractSAXParser).startElement(QName, XMLAttributes, Augmentations) line: not available  
SAXParser(AbstractXMLDocumentParser).emptyElement(QName, XMLAttributes, Augmentations) line: not available  
XMLNSDocumentScannerImpl.scanStartElement() line: not available 
XMLNSDocumentScannerImpl$NSContentDispatcher(XMLDocumentFragmentScannerImpl$FragmentContentDispatcher).dispatch(boolean) line: not available    
XMLNSDocumentScannerImpl(XMLDocumentFragmentScannerImpl).scanDocument(boolean) line: not available  
XML11Configuration.parse(boolean) line: not available   
XML11Configuration.parse(XMLInputSource) line: not available    
SAXParser(XMLParser).parse(XMLInputSource) line: not available  
SAXParser(AbstractSAXParser).parse(InputSource) line: not available 
**DescriptorRepositoryXml(XmlObject).fromXml(InputSource) line: 341 (last call within ivalidator.jar)** 

我想知道对外部类(外部 jar 以及 org.xml.sax.xmlreader )的调用是否可能会导致问题?

I am trying to use AspectJ (which until yesterday I didn’t know) with LTW in order to understand how an existing framework works.
In brief, I am interested at how framework's input XML files get parsed.

I have written the following aspect:

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.CodeSignature;

public aspect UnitContextTrace {

    static final void println(String s){ System.out.println(s); }

    pointcut unitContextMethodsExec(): call(public * org.ivalidator.framework.test.UnitContext.* (..)) ||
    call(public void org.ivalidator.repository..*.set* (..));

    Object around(): unitContextMethodsExec() {
        println("Intercepted message: " +
                thisJoinPointStaticPart.getSignature().getName());
        println("in class: " +
                thisJoinPointStaticPart.getSignature().getDeclaringType().getName());
        printParameters(thisJoinPoint);
        println("Running original method: \n" );
        Object result = proceed();
        println("  result: " + result );
        return result;
    }

    static private void printParameters(JoinPoint jp) {
        println("Arguments: " );
        Object[] args = jp.getArgs();
        String[] names = ((CodeSignature)jp.getSignature()).getParameterNames();
        Class[] types = ((CodeSignature)jp.getSignature()).getParameterTypes();
        for (int i = 0; i < args.length; i++) {
            println("  "  + i + ". " + names[i] +
                    " : " +            types[i].getName() +
                    " = " +            args[i]);
        }
    }
}

This should debug both calls to methods of UnitContext interface’s implementations and those to setXXX() methods of any class belonging to org.ivalidator.repository.* package.

I packaged my Aspect in its own jar using

 ajc UnitContextTrace.aj -outxml -outjar aspectTrace.jar -extdirs "C:\aspectj1.6\lib\"

and I started the program (I use an ant script) passing -javaagent:${aspectj.home}/lib/aspectjweaver.jar to the JVM.

The first part of the aspect (UnitContext methods) works and I can see for example

Intercepted message: getAdapter…

But unfortunately there are no logs for calls to setXXX() methods. The package org.ivalidator.repository.* is part of ivalidator.jar, which of course uses 3rd parties libraries stored in a lib folder. The structure is something like this:

  • Ivalidator.jar
  • /lib
    • Castor-0.9.7.jar
    • xercesImpl.jar

Using the debugger, I noticed that setXXX() methods are invoked from external classes (belonging to castor-0.9.7.jar, which in turn are invoked by xerces’ classes). To be more precise, the stack trace I can see in the debugger is this:

**ParameterXml.setName(String) line: 60 (I want to intercept this)**
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]  
NativeMethodAccessorImpl.invoke(Object, Object[]) line: not available   
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: not available   
Method.invoke(Object, Object...) line: not available    
FieldHandlerImpl.setValue(Object, Object) line: 501 
UnmarshalHandler.processAttribute(String, String, String, XMLFieldDescriptor, XMLClassDescriptor, Object) line: 3028    
UnmarshalHandler.processAttributes(AttributeSet, XMLClassDescriptor) line: 2702 
UnmarshalHandler.startElement(String, String, AttributeSet) line: 2325  
UnmarshalHandler.startElement(String, String, String, Attributes) line: 1388    
SAXParser(AbstractSAXParser).startElement(QName, XMLAttributes, Augmentations) line: not available  
SAXParser(AbstractXMLDocumentParser).emptyElement(QName, XMLAttributes, Augmentations) line: not available  
XMLNSDocumentScannerImpl.scanStartElement() line: not available 
XMLNSDocumentScannerImpl$NSContentDispatcher(XMLDocumentFragmentScannerImpl$FragmentContentDispatcher).dispatch(boolean) line: not available    
XMLNSDocumentScannerImpl(XMLDocumentFragmentScannerImpl).scanDocument(boolean) line: not available  
XML11Configuration.parse(boolean) line: not available   
XML11Configuration.parse(XMLInputSource) line: not available    
SAXParser(XMLParser).parse(XMLInputSource) line: not available  
SAXParser(AbstractSAXParser).parse(InputSource) line: not available 
**DescriptorRepositoryXml(XmlObject).fromXml(InputSource) line: 341 (last call within ivalidator.jar)** 

I wonder whether calls to external classes (external jars but also i.e. org.xml.sax.xmlreader) may cause the problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

海的爱人是光 2024-12-14 04:24:01

我猜你不想拦截call(),而是拦截execution()。在这种情况下,您的第三方类是否编织并不重要。

I guess you do not want to intercept call(), but execution(). In that case it does not matter whether your third party classes are woven or not.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文