2015-12-16 1 views
0

Я хочу, чтобы моя точка вырезать, чтобы пометить вызов любым способом, за исключением тех, в Java SDKPointcut в соответствии звонить любым способом, за исключением тех, FRM JDK

Pointcut trace(): call(* *(..)) && !within(methodprofilt) && !call(* java*(..) 

Это не работает

+0

Я бы сказал, что это невозможно, потому что я могу создать класс в пакете с именем 'java.util', если захочу (если у вас нет списка классов JDK) –

+0

Итак, как я могу избежать классов java jdk и позволяет скажем, я не создаю класс в java.util еще почему он не работает – user1568701

ответ

1

Я думаю, что это не так просто, если вы смотрите в JDK вы видите, кроме java..* гораздо больше имен пакетов. Проверьте мой пример кода, который использует классы JDK от других пакетов (есть еще больше, это просто немного витрина), некоторые для нормального доступа и другие для ограниченного доступа:

Вспомогательный класс:

package de.scrum_master.app; 

public class Foo { 
    public static void doSomething() { 
     System.out.println("Doing something"); 
    } 
} 
применение

Driver:

package de.scrum_master.app; 

import javax.swing.event.EventListenerList; 
import org.ietf.jgss.GSSException; 
import org.ietf.jgss.Oid; 
import org.omg.CORBA.IntHolder; 
import org.w3c.dom.bootstrap.DOMImplementationRegistry; 
import org.xml.sax.InputSource; 

// Internal Sun/Oracle-specific JDK classes, 
// not recommended for JDK- and version-agnostic use 
import sun.util.calendar.CalendarUtils; 
import com.sun.beans.finder.BeanInfoFinder; 

public class Application { 
    public static void main(String[] args) 
     throws GSSException, ClassNotFoundException, InstantiationException, 
     IllegalAccessException, ClassCastException 
    { 
     sayHelloTo("world"); 
     Foo.doSomething(); 
     new Oid("1.2.840.113554.1.2.2").getDER(); 
     System.out.println("Process ID (PID) = " + getPID()); 
     new IntHolder(11)._type(); 
     DOMImplementationRegistry.newInstance().getDOMImplementation("XML 3.0"); 
     new InputSource().setEncoding("UTF-8"); 
     new EventListenerList().getListenerCount(); 

     // Internal Sun/Oracle-specific JDK classes, 
     // not recommended for JDK- and version-agnostic use 
     new BeanInfoFinder().getPackages(); 
     new CalendarUtils().isGregorianLeapYear(2015); 
    } 

    public static void sayHelloTo(String visitor) { 
     System.out.println("Hello " + visitor); 
    } 

    public static long getPID() { 
     String processName = java.lang.management.ManagementFactory.getRuntimeMXBean().getName(); 
     return Long.parseLong(processName.split("@")[0]); 
    } 
} 

Улучшенный перехватчик аспект:

package de.scrum_master.aspect; 

public aspect NonJDKInterceptor { 
    pointcut allCalls() : call(* *(..)); 
    pointcut jdkCalls() : 
     call(* java..*(..)) || call(* javax..*(..)) || 
     call(* org.ietf..*(..)) || call(* org.omg..*(..)) || 
     call(* org.w3c..*(..)) || call(* org.xml..*(..)) || 
     call(* sun..*(..)) || call(* com.sun..*(..)); 

    before() : allCalls() && !jdkCalls() && !within(NonJDKInterceptor) { 
     System.out.println(thisJoinPoint); 
    } 
} 

Консоль вывода:

call(void de.scrum_master.app.Application.sayHelloTo(String)) 
Hello world 
call(void de.scrum_master.app.Foo.doSomething()) 
Doing something 
call(long de.scrum_master.app.Application.getPID()) 
Process ID (PID) = 13948 

Ваш простой срез точек пропустит большую часть JDK вызовов. С помощью всего этого срезом точек

pointcut jdkCalls() : call(* java..*(..)); 

выход будет выглядеть следующим образом:

call(void de.scrum_master.app.Application.sayHelloTo(String)) 
Hello world 
call(void de.scrum_master.app.Foo.doSomething()) 
Doing something 
call(byte[] org.ietf.jgss.Oid.getDER()) 
call(long de.scrum_master.app.Application.getPID()) 
Process ID (PID) = 13748 
call(TypeCode org.omg.CORBA.IntHolder._type()) 
call(DOMImplementationRegistry org.w3c.dom.bootstrap.DOMImplementationRegistry.newInstance()) 
call(DOMImplementation org.w3c.dom.bootstrap.DOMImplementationRegistry.getDOMImplementation(String)) 
call(void org.xml.sax.InputSource.setEncoding(String)) 
call(int javax.swing.event.EventListenerList.getListenerCount()) 
call(String[] com.sun.beans.finder.BeanInfoFinder.getPackages()) 
call(boolean sun.util.calendar.CalendarUtils.isGregorianLeapYear(int)) 

Update: Я забыл упомянуть альтернативу с использованием execution() Pointcut вместо call(), потому что они

  • являются более эффективными, поскольку y создайте байт-код, где выполняется метод, а не в сотне мест, где он вызывается,
  • только вплетены в ваш собственный код по умолчанию, то есть вы все равно не переплетаетесь в двоичные файлы JDK, и, таким образом, выполнение JDK-методов игнорируется по умолчанию , Упрощенный аспект становится:
  • выход
package de.scrum_master.aspect; 

public aspect NonJDKInterceptor { 
    before() : execution(* *(..)) { 
     System.out.println(thisJoinPoint); 
    } 
} 

Журнал похож на первый, но теперь он также перечисляет выполнение main(..) метода:

execution(void de.scrum_master.app.Application.main(String[])) 
execution(void de.scrum_master.app.Application.sayHelloTo(String)) 
Hello world 
execution(void de.scrum_master.app.Foo.doSomething()) 
Doing something 
execution(long de.scrum_master.app.Application.getPID()) 
Process ID (PID) = 13916 

Я думаю, что это просто и эффективное решение, которое вы хотите. Отвечать на вопрос call() pointcuts было именно то, что вы просили.

0

Pointcut Я искал был

call(java..*..*(..)) 
+1

На самом деле синтаксис здесь неверен.Вы имеете в виду 'call (* java .. * (..))'. Но в любом случае это не правильное решение, см. Мой собственный ответ. – kriegaex