<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <body> <a href="user_guide.html">[index]</a><br> <a href="reflection.html">[prev]</a> <a href="events.html">[next]</a> <h1>2. Jiapi Framework</h1> This chapter describes Jiapi's instrumentation framework. It utilizes Jiapi reflection API which was introduced in a previous chapter. The aim is to provide a framework where bytecode manipulations can be logically grouped and reused. <p> <h2>2.1 Introduction</h2> The instrumentation process consists of three tasks: <i>configuration</i>, <i>instrumentation</i> and <i>launching</i>. <h3>Configuration</h3> Configuration specifies the classes and methods for which instrumentation will be done. It also specifies the characteristics of instrumentations. <h3>Instrumentation</h3> Instrumentation is a process of transforming the original Java class into a modified class. The modifications must be done before actual class loading since after a class has been loaded into a Java virtual machine it is not possible to change it anymore (well actually it is possible if the <code>ClassLoader</code> which loaded the class is garbage collected, but that's another story...). Jiapi provides a class <code>alt.jiapi.Loader</code> which can be used to form an in-memory representation for a class (<code>alt.jiapi.reflect.JiapiClass</code>). 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. <p> After <code>alt.jiapi.Loader</code> has formed an instance of <code>alt.jiapi.reflect.JiapiClass</code> from Java bytecode, it triggers the instrumentation process according to its configuration. <p> <img src="uml/jiapi_framework.gif"> <p> Roles and responsibilities: <ul> <li><b>Instrumentor</b><br> <code>Instrumentor</code> is responsible to instrument its target. It can modify or just analyze the target <code>InstructionList</code> which is passed to it. <li><b>InstrumentorChain</b><br> Defines a pipeline for <code>Instrumentors</code>. Jiapi framework is implemented using Filter design pattern where <code>Instrumentors</code> take a role of a filter. <li><b>InstrumentationDescriptor</b><br> Conceptually encloses all the <i>instrumentations</i> which share the same set of <i>Rules</i>. Therefore, the <i>instrumentations</i> within a same descriptor will be carried on a same set of classes. <li><b>InstrumentationContext</b><br> Context is used to group all the <code>InstrumentationDescriptors</code> together. </ul> <h3>Launching</h3> <p> Often the classes are loaded into a virtual machine after they have been modified. <code>alt.jiapi.InstrumentingClassLoader</code> 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. <h2>2.2 InstrumentorChain and Instrumentors</h2> A configurable chain of <code>Instrumentors</code> form a backbone of the framework. The chain is implemented as a filter design pattern where each <code>Instrumentor</code> acts as a filter for an <code>InstructionList</code> stream. <p> <img src="uml/instrumentor_chain.gif"> <p> The most important method which they implement is: <br> <pre> public interface Instrumentor { /** * Instrument given InstructionList. * * @param il An InstructionList to instrument */ public void instrument(InstructionList il); ... ... } </pre> On <code>instrument</code> method each <code>Instrumentor</code> may manipulate the given <code>InstructionList</code>. The control is then dispatched to the next <code>Instrumentor</code> using <code>forward</code> method. An example of a simple <code>Instrumentor</code> is <code>ClearInstrumentor</code> which clears the instructions from a given <code>InstructionList:</code> <pre> public class ClearInstrumentor extends AbstractInstrumentor { public ClearInstrumentor() { } public void instrument(InstructionList il) { il.clear(); forward(il); } } </pre> Jiapi provides a set of predefined <code>Instrumentors</code>. These can be found from a package <code>alt.jiapi.instrumentor</code>. Here's a brief description of each: <ul> <li><b>ClearInstrumentor</b></li> Clears the <code>InstructionList</code> which is forwarded to it.<br> <li><b>GrepInstrumentor</b></li> Greps the given <code>InstructionList</code> according to a configured strategy. The grep splits the <code>InstructionList</code> from the matching parts and then forwards each sublist. Examples of strategies are <code>MethodCallStrategy</code> which greps the list from places where a method call is made, or <code>FieldAccessStrategy</code> which greps the list from places where a field is referenced. <li><b>SplitInstrumentor</b></li> Splits the given <code>InstructionList</code> according to a configured strategy. This is very similar to the <code>GrepInstrumentor</code>. The difference is whereas <code>GrepInstrumentor</code> forwards only the instructions which matched the given startegy, <code>SplitInstrumentor</code> forwards sublists which are separated from a matching instruction. <li><b>HeadInstrumentor</b></li> Forwards the beginning of an <code>InstructionList</code>. <li><b>TailInstrumentor</b></li> Forwards the ending of an <code>InstructionList</code>. <li><b>CreateFieldInstrumentor</b></li> Creates a field to a class which contains the given <code>InstructionList</code>. <li><b>CreateMethodInstrumentor</b></li> Creates a method to a class which contains the given <code>InstructionList</code>. <li><b>FieldAssignInstrumentor</b></li> Creates bytecode which assigns a value for a field. <li><b>MethodCallInstrumentor</b></li> Creates bytecode which makes a method call. <li><b>CopyInstrumentor</b></li> Copies bytecode to the given <code>InstructionList</code>. </ul> <p> 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. <p> <p> <a href="reflection.html">[prev]</a> <a href="events.html">[next]</a> </body> </html>