Chapter 3. Pointcut and Type Expressions

3.1. Wildcards

There are two types of wildcards you can use within pointcut expressions

  • * Is a regular wildcard that matches zero or more characters. It can be used within any type expression, field, or method name, but not in an annotation expression
  • .. Is used to specify any number of parameters in an constructor or method expression.

3.2. Type Patterns

Type patterns are defined by an annotation or by fully qualified class name. Annotation expressions are not allowed to have wildcards within them, but class expressions are.

  • org.acme.SomeClass matches that class.
  • org.acme.* will match org.acme.SomeClass as well as org.acme.SomeClass.SomeInnerClass
  • @javax.ejb.Entity will match any class tagged as such.
  • String or Object are illegal. You must specify the fully qualified name of every java class. Even those under the java.lang package.

To reference all subtypes of a certain class (or implementors of an interface), the $instanceof{} expression can be used. Wildcards and annotations may also be used within $instanceof{} expressions.

         $instanceof{org.acme.SomeInterface}
         $instanceof{@org.acme.SomeAnnotation}
         $instanceof{org.acme.interfaces.*}
      

are all allowed.

For very complex type expressions, the Typedef construct can be used. To reference a Typedef within a class expression $typedef{id} is used.

3.3. Method Patterns

public void org.acme.SomeClass->methodName(java.lang.String)

The attributes( public, static, private) of the method are optional. If the attribute is left out then any attribute is assumed. Attributes accept the ! modifier for negation.

public !static void org.acme.SomeClass->*(..)

$instanceof{} in the class name.

void $instanceof{org.acme.SomeInterface}->methodName(java.lang.String)

To only match methods from a given interface you can use the $implements{} or $implementing{} keywords in place of the method name. $implements{} only matches methods from the exact interface(s) given, while $implementing{} matches methods from the interface(s) given AND their super interfaces.

void $instanceof{org.acme.IfA}->$implements(org.acme.IfA)
void $instanceof{org.acme.IfB}->$implementing(org.acme.IfA, org.acme.IfB)

Annotations can be used in place of the class name. The below example matches any methodName() of a tagged @javax.ejb.Entity class.

void @javax.ejb.Entity->methodName(java.lang.String)

Annotations can be also be used in place of the method name. The below examples matches any method tagged as @javax.ejb.Tx.

* *->@javax.ejb.Tx(..)

In addition you can use typedefs, $instanceof{}, annotations and wildcards for method parameters and return types. The following matches all methods called loadEntity that return a class annotated with @javax.ejb.Entity, that takes a class annotated as @org.acme.Ann and any class that matches java.*.String (such as java.lang.String).

@javax.ejb.Entity *->loadEntity(@org.acme.Ann, java.*.String)
You can also include an optional throws clause in the pointcut expression:
public void org.acme.SomeClass->methodName(java.lang.String) \
      throws org.acme.SomeException, java.lang.Exception
If any exceptions are present in the pointcut expression they must be present in the throws clause of the methods to be matched.

3.4. Constructor Patterns

public org.acme.SomeClass->new(java.lang.String)

Constructor expressions are made up of the fully qualified classname and the new keyword The attributes( public, static, private) of the method are optional. If the attribute is left out then any attribute is assumed. Attributes accept the ! modifier for negation.

!public org.acme.SomeClass->new(..)

$instanceof{} can be used in the class name.

$instanceof{org.acme.SomeInterface}->new(..)

Annotations can be used in place of the class name. The below example matches any constructor of a tagged @javax.ejb.Entity class.

@javax.ejb.Entity->new(..)

Annotations can be also be used in place of the new keyword. The below examples matches any constructor tagged as @javax.ejb.MethodPermission.

*->@javax.ejb.MethodPermission(..)

In addition, just as for methods you can use typedefs, $instanceof{}, annotations and wildcards for constructor parameters. The following matches all constructors that take a class annotated as @org.acme.Ann and any class that matches java.*.String (such as java.lang.String).

*->new(@org.acme.Ann, java.*.String)

You can also include an optional throws clause in the pointcut expression:

public void org.acme.SomeClass->new(java.lang.String) \
      throws org.acme.SomeException, java.lang.Exception

If any exceptions are present in the pointcut expression they must be present in the throws clause of the constructors to be matched.

3.5. Field Patterns

public java.lang.String org.acme.SomeClass->fieldname

Constructor expressions are made up of the type, the fully qualified classname where the field resides and the field's name. The attributes( public, static, private) of the field are optional. If the attribute is left out then any attribute is assumed. Attributes accept the ! modifier for negation.

!public java.lang.String org.acme.SomeClass->*

$instanceof{} can be used in the class name. The below expression matches any field of any type or subtype of org.acme.SomeInterface

* $instanceof{org.acme.SomeInterface}->*

Annotations can be used in place of the class name. The below example matches any field where the type class is tagged with @javax.ejb.Entity.

* @javax.ejb.Entity->*

Annotations can be also be used in place of the field name. The below examples matches any field tagged as @org.jboss.Injected.

* *->@org.jboss.Injected

In addition, you can use typedefs, $instanceof{}, annotations and wildcards for field types. The following matches all fields where the type class has been tagged with @javax.ejb.Entity.

@javax.ejb.Entity *->*

3.6. Pointcuts

Pointcuts use class, field, constructor, and method expressions to specify the actual joinpoint that should be intercepted/watched.

execution(method or constructor)
execution(public void Foo->method()
execution(public Foo->new())

execution is used to specify that you want an interception to happen whenever a method or constructor is called. The the first example of matches anytime a method is called, the second matches a constructor. System classes cannot be used within execution expressions because it is impossible to instrument them.

construction(constructor)
construction(public Foo->new())

construction is used to specify that you want aspects to run within the constructor. The execution pointcut requires that any code that calls new() must be instrumented by the compiler. With construction the aspects are weaved right within the constructor after all the code in the constructor. The aspects are appended to the code of the constructor.

get (field expression) B b b b B b b
get(public int Foo->fieldname)

get is used to specify that you want an interception to happen when a specific field is accessed for a read.

set(field expression)
get(public int Foo->fieldname)

set is used to specify that you want an interception to happen when a specific field is accessed for a write.

field(field expression)
field(public int Foo->fieldname)

field is used to specify that you want an interception to happen when a specific field is accessed for a read or a write.

all(type expression)
all(org.acme.SomeClass)
all(@org.jboss.security.Permission)

all is used to specify any constructor, method or field of a particular class will be intercepted. If an annotation is used, it matches the member's annotation, not the class's annotation.

call(method or constructor)
call(public void Foo->method()
call(public Foo->new())

call is used to specify any constructor or method that you want intercepted. It is different than execution in that the interception happens at the caller side of things and the caller information is available within the Invocation object. call can be used to intercept System classes because the bytecode weaving happens within the callers bytecode.

within(type expression)
within(org.acme.SomeClass)
within(@org.jboss.security.Permission)

within matches any joinpoint (method or constructor call) within any code within a particular call.

withincode(method or constructor)
withincode(public void Foo->method()
withincode(public Foo->new())

withincode matches any joinpoint (method or constructor call) within a particular method or constructor.

has(method or constructor)
has(void *->@org.jboss.security.Permission(..))
has(*->new(java.lang.String))

has is an additional requirement for matching. If a joinpoint is matched, its class must also have a constructor or method that matches the has expression.

hasfield(field expression)
hasfield(* *->@org.jboss.security.Permission)
hasfield(public java.lang.String *->*)

has is an additional requirement for matching. If a joinpoint is matched, its class must also have a field that matches the hasfield expression.

3.7. Pointcut Composition

Pointcuts can be composed into boolean expressions.

  • ! logical not.
  • AND logical and.
  • OR logical or.
  • Parathesis can be used for grouping expressions.

Here's some examples.

call(void Foo->someMethod()) AND withincode(void Bar->caller())
execution(* *->@SomeAnnotation(..)) OR field(* *->@SomeAnnotation)

3.8. Pointcut References

Pointcuts can be named in XML or annotation bindings (See in later chapters). They can be referenced directly within a pointcut expression.

some.named.pointcut OR call(void Foo->someMethod())

3.9. Typedef Expressions

Sometimes, when writing pointcuts, you want to specify a really complex type they may or may not have boolean logic associated with it. You can group these complex type definitions into a JBoss AOP Typedef either in XML or as an annotation (See later in this document). Typedef expressions can also be used within introduction expressions. Typedef expressions can be made up of has, hasfield, and class expressions. class takes a fully qualified class name, or an $instanceof{} expression.

class(org.pkg.*) OR has(* *->@Tx(..)) AND !class($instanceof{org.foo.Bar})