2013-03-24 210 views
0

我試圖訪問使用aspectJ的參數的名稱,但我總是得到arg0而不是真實名稱。我發現,我應該激活與-g參數Java調試選項在AspectJ JoinPoint question但是,這並不爲我工作...如何在使用AspectJ的eclipse中啓用調試符號?

這是我的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

我還需要激活什麼?

非常感謝!

回答

1

我發現知道變量的名稱(標識)用下面的切入點更好的辦法:

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

這樣,我們可以得到一個直接引用變量Ç。在Eclipse

激活調試符號是沒有必要的。

所需的解決方案可以用下面的代碼來實現:

的Instrumentator:

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!"); 
     } 
    } 

} 
0

我讀了你所要求的Set.add(..)的第一個參數的(內部)名稱的方式 - 方法。這絕不會是您定義的名稱,因爲它是Java-API的一部分。你想要的是傳遞給該參數的的名稱。

值應該作爲對象[]通過JoinPoint.getArgs()-method,但我不會馬上知道如何讓自己的名字。應儘可能通過反思。

+0

謝謝您的幫助。我必須做的是:在方法** s.add(c)**內部**我需要訪問** c **變量名來保存它,並稍後在另一個Aspectj中監視它。 – 2013-03-25 16:43:19