如何使用AspectJ在eclipse中启用调试符号?

时间:2013-03-24 17:50:17

标签: java eclipse aspectj

我正在尝试使用aspectJ访问参数的名称,但我总是得到 arg0 而不是真正的名称。我发现我应该在AspectJ JoinPoint question使用-g参数激活java调试选项,但这对我不起作用...

这是我的java代码:

private Set<Collection<String>> s;
private Collection<String> c;

public HashCodeProperty() {
    s = new HashSet<Collection<String>>();
    c = new ArrayList<String>();
}

/**
 * method that satisfy property
 */
public void satisfy() {
    c.add("this is ok");
    s.add(c);
    System.out.println("Collection is in Set: " + s.contains(c));
}

/**
 * method that violate the property
 */
public void violate() {
    c.add("this is ok");
    s.add(c);
    c.add("don't do this");
    System.out.println("Collection is in Set: " +s.contains(c));
}

这是我的AspectJ代码:

pointcut addElementsToHashCodeSet() : call (* Set.add(..));

declare warning: addElementsToHashCodeSet(): "pointcut: addElementsToHashCode()";

after(): addElementsToHashCodeSet() { 
    monitorHashCode.addElementsToHashCode((MethodSignature)thisJoinPoint.getSignature());



public void addElementsToHashCode(MethodSignature methodSignature) { 
    System.out.println("\naddElementsToHashCode.");

    // We need to access to real PARAMETER NAME
    // Then we will concatenate with method and full class name
    String firstParameterName = methodSignature.getParameterNames()[0];
    // Add firstParameterName to an array that will contain all 
    // the name of the collections inserted into the HasSet 
    System.out.println("\nfirstParameterName: "+firstParameterName);
}

当前输出:

firstParameterName:arg0

我需要输出的内容:

firstParameterName:c

我有两个选择:

Java compiler options

AspectJ compiler options

我还需要激活什么?

非常感谢!

2 个答案:

答案 0 :(得分:1)

我找到了一种更好的方法来知道变量的名称(标识符),并带有以下切点:

before(Collection c): addElementsToHashCodeSet() && args(c)

通过这种方式,我们可以直接引用变量 c

不需要在eclipse中激活调试符号。

可以使用以下代码实现所需的解决方案:

仪器人:

package fr.imag.ufrima.tat.tp6.aspects;

import java.util.Collection;
import java.util.Set;

import fr.imag.ufrima.tat.tp6.aspects.monitor.MonitorHashCode;

/**
 * Techniques Avancées de Test
 * 
 * @author Rodmar CONDE
 *
 * Instrumentator for validation of HashSet classes.
 * 
 * Secures the usage of HashSet that include Collections in preventing 
 * more elements to be added to the collections once they are added. 
 * 
 * Monitor code is provided in a separate class: MonitorHashCode.
 */
public aspect InstrumentationHashCode {

    private MonitorHashCode monitorHashCode;

    public InstrumentationHashCode() {
        monitorHashCode = new MonitorHashCode();
    }

    pointcut addElementsToHashCodeSet() : call (* Set.add(..));

    declare warning: addElementsToHashCodeSet(): "pointcut: addElementsToHashCode()";

    before(Collection c): addElementsToHashCodeSet() && args(c) { 
        monitorHashCode.addElementsToHashCode(c);                   
    }

    pointcut addElementsToCollection() : call (* Collection.add(..));

    declare warning: addElementsToCollection(): "pointcut: addElementsToCollection()";

    after(String s): addElementsToCollection() && args(s) {
        monitorHashCode.addElementsToCollection(thisJoinPoint.getTarget());     
    }

}

监视器:

package fr.imag.ufrima.tat.tp6.aspects.monitor;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * 
 * @author Rodmar CONDE
 * 
 * Monitor used to prevent adding elements to a collection that has already been added to a HashMap
 *
 */
public class MonitorHashCode {
    /**
     *  Stores the system identity hashcode of the collections that are added to the monitored HashCode 
     */
    private List<Integer> collectionsAddedToHashSet;

    public MonitorHashCode() {
        System.out.println("Monitor created.");
        collectionsAddedToHashSet = new ArrayList<Integer>();
    }

    /**
     * Adds the system identity hashcode of the passed collection to the list
     * 
     * @param c Collection to be added to the list
     */
    public void addElementsToHashCode(Collection c) { 
        System.out.println("\naddElementsToHashCode.");

        collectionsAddedToHashSet.add(System.identityHashCode(c));
        System.out.println("\nCollection has been added to HashMap.");
    }

    /**
     * 
     * Before adding the element, search if the collection exists already
     * in the list, if so print an error.
     *
     * @param pointCutTarget
     */
    public void addElementsToCollection(Object pointCutTarget) { 
        System.out.println("\naddElementsToCollection.");

        int systemIdentityHashCode = System.identityHashCode(pointCutTarget);
        boolean isContained = collectionsAddedToHashSet.contains(systemIdentityHashCode);
        System.out.println(String.format("currentCollection: %s systemIdentityHashCode: %d - isContained: %s", pointCutTarget, systemIdentityHashCode, isContained));
        if (isContained) {
            System.out.println("Error: you have already added this collection into a hashmap, you can not add more elements into it!");
        }
    }

}

答案 1 :(得分:0)

我读它的方式是你要求Set.add(..) - 方法的第一个参数的(内部)名称。这永远不会是您定义的名称,因为它是Java-API的一部分。您想要的是传递给该参数的的名称。

这些值应该通过JoinPoint.getArgs()-method以Object []的形式提供,但我不能立即确定如何获取它们的名称。应该可以通过反思来实现。