0

I want my point cut to mark call to any method except those in java sdk

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

This doesnt work

HaveNoDisplayName
  • 8,291
  • 106
  • 37
  • 47
user1568701
  • 43
  • 3
  • 11
  • I would say that's not possible, because I can create a class in a package named `java.util` if I want (unless you have a list of JDK classes) –  Dec 16 '15 at 18:38
  • So how can I avoid classes of java jdk and lets say I am not creating class in java.util still why isnt it working – user1568701 Dec 17 '15 at 03:41

2 Answers2

1

I think it is not so easy, if you look into the JDK you see a lot more package names other than java..*. Check out my sample code which uses JDK classes from other packages (there are even more, this is just a little showcase), some for normal access and others for restricted access:

Helper class:

package de.scrum_master.app;

public class Foo {
    public static void doSomething() {
        System.out.println("Doing something");
    }
}

Driver application:

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]);
    }
}

Improved interceptor aspect:

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

Console output:

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

Your simple pointcut would miss most of the JDK calls. With just this pointcut

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

the output would look as follows:

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: I forgot to mention the alternative of using an execution() pointcut instead of call(), because they

  • are more efficient because they create bytecode where a method is executed, not in a hundred places where it is called,
  • are only woven into your own code by default, i.e. you do not weave into JDK binaries anyway and thus JDK method executions are ignored by default. The simplified aspect becomes:
package de.scrum_master.aspect;

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

The log output is similar to the first one, but now it also lists the execution of the main(..) method:

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

I think this is the simple and efficient solution you want. May answer about call() pointcuts was just what you asked for.

kriegaex
  • 63,017
  • 15
  • 111
  • 202
0

Pointcut I was looking for was

call(java..*..*(..))
krock
  • 28,904
  • 13
  • 79
  • 85
user1568701
  • 43
  • 3
  • 11
  • 1
    Actually the syntax here is wrong. What you mean is `call(* java..*(..))`. But it is not the correct solution anyway, see my own answer. – kriegaex Dec 28 '15 at 23:51