ClassLoader which loaded the class is garbage
collected, but that's another story...). Jiapi provides a class
alt.jiapi.Loader which can be used to form an in-memory
representation for a class (alt.jiapi.reflect.JiapiClass). It
is important to understand that in this phase the class is not really
loaded into a virtual machine. It is just an object representation
of Java bytecode.
After alt.jiapi.Loader has formed an instance of
alt.jiapi.reflect.JiapiClass from Java bytecode, it triggers
the instrumentation process according to its configuration.
Roles and responsibilities:
Instrumentor is responsible to instrument its target.
It can modify or just analyze the target InstructionList
which is passed to it.
Instrumentors. Jiapi framework
is implemented using Filter design pattern where Instrumentors
take a role of a filter.
InstrumentationDescriptors
together.
Often the classes are loaded into a virtual machine after they have been
modified. alt.jiapi.InstrumentingClassLoader is an example
Java class loader which can be used to load classes into a virtual machine
after they have been modified by Jiapi instrumentors. The modified
classes can also be saved to filesystem and run later with any virtual
machine.
Instrumentors form a backbone of the
framework. The chain is implemented as a filter design pattern where
each Instrumentor acts as a filter for an
InstructionList stream.
The most important method which they implement is:
public interface Instrumentor {
/**
* Instrument given InstructionList.
*
* @param il An InstructionList to instrument
*/
public void instrument(InstructionList il);
...
...
}
On instrument method each Instrumentor may
manipulate the given InstructionList. The control
is then dispatched to the next Instrumentor using
forward method. An example of a simple
Instrumentor is ClearInstrumentor which
clears the instructions from a given InstructionList:
public class ClearInstrumentor extends AbstractInstrumentor {
public ClearInstrumentor() {
}
public void instrument(InstructionList il) {
il.clear();
forward(il);
}
}
Jiapi provides a set of predefined Instrumentors. These can be
found from a package alt.jiapi.instrumentor. Here's
a brief description of each:
InstructionList which is forwarded to it.InstructionList according to a configured
strategy. The grep splits the InstructionList from
the matching parts and then forwards each sublist. Examples of
strategies are MethodCallStrategy which greps the list
from places where a method call is made, or FieldAccessStrategy
which greps the list from places where a field is referenced.
InstructionList according to a configured
strategy. This is very similar to the GrepInstrumentor.
The difference is whereas GrepInstrumentor forwards
only the instructions which matched the given startegy,
SplitInstrumentor forwards sublists which are separated
from a matching instruction.
InstructionList.
InstructionList.
InstructionList.
InstructionList.
InstructionList.
The instrumentors are chained together to do something useful. A good analogy for this chaining is Unix shell pipeline where small utility programs are piped together.