The JRockit JVM AOP support exposes a Java API that is deeply integrated in the JVM method dispatching and object model components. To make sure not to tie the JVM to any current or future AOP-specific technology direction, we have decided to implement an action dispatch and subscription model.
The API allows you to describe well-defined subscriptions at specified pointcuts, for which it is possible to register one action to which the JVM will dispatch. An action is composed of:
The action can be flagged as a before action, an after returning action, an after throwing action, or an instead-of action (similar to AOP around concept).
To invoke the API, you must get a handle to a
jrockit.ext.weaving.Weaver instance. The weaver instance controls which operations are allowed according to its
caller context. For example, you may not want a deployed application in an application server to create a weaver to subscribe action methods to some container-level or JDK-specific join points, while a container-level weaver may actually subscribe to application-specific join points. This weaver visibility concept mirrors the visibility rules from the underlying classloader's delegation model.
A simple comparison of how these constructs are mapped to the regular AOP constructs may shed some light on this model:
get(),
set(), method
call(), and so on) composed with a
within()/withincode() pointcut.
Readers familiar with AOP may already understand that to implement a complete AOP framework on top of this JVM-level API, some more development is required on an intermediate layer that will manage the aspect instantiation models (per clause), on implementing the
cflow() pointcuts, and on implementing full pointcut composition and orthogonality.
An action method (similar to the AOP advice concept) is like a regular Java method of a regular class (that acts as the aspect). It can either be a
static method or a member method. Its return type has to follow some implicit conventions and should be
void for a before action. It should also be of the type that will be placed on the stack as the result of the action invocation for an instead-of action (similar to AOP around advice semantics).
The action method can have parameters, whose annotations further control context exposure, as illustrated in the following code sample:
import java.lang.reflect.*;
import jrockit.ext.weaving.*;
public class SimpleAction {
public static void simpleStaticAction() {
out.println("hello static action!");
}
public void simpleAction() {
out.println("hello action!");
}
public void simpleAction(
@CalleeMethod WMethod calleeM,
@CallerMethod WMethod callerM) {
out.println(callerM.getMethod().getName());
out.println(" calling ");
out.println(calleeM.getMethod().getName());
}
}
This code sample introduces the
jrockit.ext.weaving.WMethod class. This class acts as a wrapper for
java.lang.reflect.Method,
java.lang.reflect.Constructor, and the class's
static initializer, which is not represented in
java.lang.reflect.*. This is similar to the AspectJ
JoinPoint.StaticPart.getSignature() abstractions.
Here is a list of the current set of defined annotations and their meaning:
| Annotation | Exposes | Notes |
|---|---|---|
@CalleeMethod
|
The callee method (method, constructor, static initializer) | |
@CallerMethod
|
The caller method (method, constructor, static initializer) | |
@Callee
|
The callee instance | Filters out static members invocation. Acts as an instance-of type filter: The callee type must be an instance of the annotated argument type. |
@Caller
|
The caller instance | Filters out invocations from within static members. Acts as an instance-of type filter: The caller type must be an instance of the annotated argument type. |
@Arguments
|
The invocation arguments |
To support instead-of and the ability to decide whether to proceed along the interception chain or not (as implemented in AOP through the concept of
JoinPoint.proceed()), we introduced the
jrockit.ext.weaving.InvocationContext construct as illustrated below.
import jrockit.ext.weaving.*;
public class InsteadOfAction {
public Object instead(
InvocationContext jp,
@CalleeMethod Method callee) {
return jp.proceed();
}
}
