To utilize the events, application developer implements a listener interface and registers it to an event producer. Current implementation provides a notification mechanism for following events:
alt.jiapi.event.MethodListener
interface.
The interface provides callback methods to get notification when
a method is entered or when a method exits:
public interface MethodListener extends JiapiListener { /** * Called when a method is entered. * @param event a MethodEvent describing which method triggered * this event */ public void methodEntered(MethodEvent event); /** * Called just before method is exiting. * @param event a MethodEvent describing which method triggered * this event */ public void methodExited(MethodEvent event); }
alt.jiapi.event.FieldListener
interface.
public interface FieldListener extends JiapiListener { /** * Called just before a field is changed. */ public void fieldChanging(FieldEvent fe); /** * Called after a field has been set. */ public void fieldSet(FieldEvent fe); /** * Called when someone is getting a field. */ public void fieldGet(FieldEvent fe); }
alt.jiapi.event.ExceptionListener
interface.
MethodListener
interface,
registers itself to a MethodEventProducer
and
launches a test class which is instrumented to fire method events.
1 package samples.example1; 2 3 import alt.jiapi.InstrumentationContext; 4 import alt.jiapi.InstrumentationDescriptor; 5 import alt.jiapi.event.MethodEvent; 6 import alt.jiapi.event.MethodEventProducer; 7 import alt.jiapi.event.MethodListener; 8 import alt.jiapi.util.Bootstrapper; 9 10 public class Example1 implements MethodListener { 11 public static void main(String args[]) throws Exception { 12 new Example1(); 13 } 14 15 public Example1() throws Exception { 16 // Configure: 17 InstrumentationContext ctx = new InstrumentationContext(); 18 InstrumentationDescriptor id = new InstrumentationDescriptor(); 19 id.addInclusionRule("test.*"); 20 ctx.addInstrumentationDescriptor(id); 21 22 // Use event API: 23 MethodEventProducer eventProducer = new MethodEventProducer(id); 24 eventProducer.addMethodListener(this); 25 26 // Launch: 27 Bootstrapper.launch("test.Foo", null, ctx, 28 getClass().getClassLoader()); 29 } 30 31 public void methodEntered(MethodEvent event) { 32 System.out.println("Method " + event.getClassName() + "." + 33 event.getMethodName() + " entered."); 34 } 35 36 public void methodExited(MethodEvent event) { 37 System.out.println("Method " + event.getClassName() + "." + 38 event.getMethodName() + " exited."); 39 } 40 }The example is a
MethodListener
, it implements the required
callback methods methodEntered
and methodExited
.
In constructor the example configures itself, registers itself to
a MethodEventProducer
and launches Jiapi in a just-in-time
bytecode weaving mode.
Lines 17-20 configures the context for the instrumentation. The context
is configured so that all the classes whose fully qualified name matches
test.*
will be included in instrumentation.
In lines 23 and 24 a MethodEventProducer
is created and
a listener is registered.
Lines 27 and 28 are used to launch a class test.Foo
with
a given InstrumentationContext
.
alt.jiapi.util.Bootstrapper
is a utility which loads the
given class with alt.jiapi.util.InstrumentingClassLoader
and
calls loaded class' main method. InstrumentingClassLoader
first forms an in-memory representation for the class, triggers the
instrumentation process for it and then loads the modified class
into a Java virtual machine.
To run the example1 put jiapi.jar and all the required third-party
libraries (these are listed in README) to your CLASSPATH and then
bootstrap it:
java alt.jiapi.util.Bootstrapper samples.example1.Example1
or more shortly:
jiapi.sh samples.example1.Example1
You should see console prints when a methods are entered and exited.
Source code for the example can be found from src/samples/example1/.