AspectJ pointcut не работает с внешними классами и LTW - PullRequest
1 голос
/ 29 сентября 2011

Я пытаюсь использовать 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, так и вызовы методов setXXX() любого класса, принадлежащего пакету org.ivalidator.repository.*.

Я упаковал свой Аспект в собственную банку, используя

 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. Структура примерно такая:

  • 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)?

1 Ответ

1 голос
/ 21 августа 2012

Полагаю, вы не хотите перехватывать call(), но execution().В этом случае не имеет значения, сотканы ли ваши сторонние классы или нет.

...