<chapter id="instrumentation">

   <title>Instrumentation</title>

      <para>In this chapter, we explain how to instrument (or "aspectize") the
         POJOs via JBossAop. There are two steps needed by JBossAop: 1) POJO
         declaration, 2) instrumentation. But depends on the JDK and instrumentation
      mode that you are using, you may not need to pre-process your POJO at all. That is,
      if you use JDK5.0 and load-time mode, then all you need to do is
      annotation your POJO (or declare it in a xml file). This makes your PojoCache
      programming nearly transparent.</para>

      <para>For the first step, since we are using the dynamic Aop feature, a
         POJO is only required to be declared "prepare". Basically, there are two
         ways to do this: either via explicit xml or annotation (new since release
         1.2.3.)</para>

      <para>As for the second step, either we can ask JBossAop to do load-time
         (through a special class loader, so-called loadtime mode) or compile-time
         instrumentation (use of an aopc pre-compiler, so-called precompiled
         mode)</para>

         <sect1>
            <title>XML descriptor</title>

            <para>To declare a POJO via XML configuration file, you will need a
               <literal>META-INF/jboss-aop.xml</literal>
               file located under the class
               path. JBossAOP framework will read this file during startup to make
               necessary byte code manipulation for advice and introduction. Or you
               can pre-compile it using a pre-compiler called
               <literal>aopc</literal>
               such that you won't need the XML file during load time. JBossAop
               provides a so-called
               <literal>pointcut</literal>
               language where it
               consists of a regular expression set to specify the interception
               points (or
               <literal>jointpoint</literal>
               in aop language). The
               jointpoint can be constructor, method call, or field. You will need to
               declare any of your POJO to be "prepared" so that AOP framework knows
               to start intercepting either method, field, or constructor invocations
               using the dynamic Aop.
            </para>

            <para>For PojoCache, we only allow all the
               fields (both read and write) to be intercepted. That is, we don't care
               for the method level interception since it is the state that we are
               interested in. So you should
               only need to change your POJO class name. For details of the pointcut
               language, please refer to JBossAop.</para>

            <para>The standalone
               <literal>JBossCache</literal>
               distribution
               package provides an example declaration for the tutorial classes,
               namely,
               <literal>Person</literal>
               and
               <literal>Address</literal>
               .
               Detailed class declaration for
               <literal>Person</literal>
               and
               <literal>Address</literal>
               are provided in the Appendix section. But here
               is the snippet for
               <literal>META-INF/jboss-aop.xml</literal>
               :
            </para>

<programlisting>
&lt;aop&gt;
  &lt;prepare expr="field(* org.jboss.test.cache.test.standAloneAop.Address-&gt;*)" /&gt;
  &lt;prepare expr="field(* $instanceof{org.jboss.test.cache.test.standAloneAop.Person}-&gt;*)" /&gt;
&lt;/aop&gt;
</programlisting>

            <para>Detailed semantics of
               <literal>jboss-aop.xml</literal>
               can again
               be found in JBossAop. But above statements basically declare all field
               read and write operations in classes
               <code>Address</code>
               and
               <code>Person</code>
               will be "prepared" (or "aspectized"). Note
               that:
            </para>

            <itemizedlist>
               <listitem>
                  The wildcard at the end of the expression signifies all fields in the POJO
               </listitem>

               <listitem>
                  You can potentially replace specific class name with wildcard that includes all the POJOs inside the
                  same package space
               </listitem>

               <listitem>
                  The

                  <code>instanceof</code>

                  operator declares any sub-type or sub-class of the specific POJO will also be "aspectized". For
                  example, if a

                  <code>Student</code>

                  class is a subclass of

                  <code>Person</code>

                  , JBossAop will automatically instrument it as well!
               </listitem>

               <listitem>
                  We intercept the field of all access levels (i.e.,

                  <literal>private</literal>

                  ,

                  <literal>protected</literal>

                  ,

                  <literal>public</literal>

                  , etc.) The main reason being that we consider all fields as stateful data. However, we can relax this
                  requirement in the future if there is a use case for it.
               </listitem>

               <listitem>
                  We don't intercept field modifiers of

                  <literal>static</literal>

                  ,

                  <literal>final</literal>

                  , and

                  <literal>transient</literal>

                  though. That is, field with these modifiers are not stored in cache and is not replicated either. If
                  you don't want your field to be managed by the cache, you can declare them with these modifiers, e.g.,
                  transient.
               </listitem>
            </itemizedlist>
         </sect1>

         <sect1>


            <title>Annotation</title>


            <para>Annotation is a new feature in Java 5.0 that when declared can
               contain metadata at compile and run time. It is well suited for aop
               declaration since there will be no need for external metadata xml
               descriptor. In order to support Java 1.4 as well, JBossAop has also used a xdoclet
               type annotation syntax, and as a result will need an annotation
               pre-compiler.</para>


            <para>Note that PojoCache starts to support the use of annotation since
               release 1.2.3 with Java 1.4, and release 1.3 with Java 5.0.
                      </para>
               <sect2>
                  <title>JDK1.4</title><para>
               In order to provide maximum transparency,
               we have created two aop marker interfaces:
               <code>@@org.jboss.cache.aop.AopMarker</code>
               and
               <code>@@org.jboss.cache.aop.InstanceOfAopMarker.</code>
               The first
               interface is used to declare a regular POJO, while the latter one is
               used to declare the POJO and its sub-classes or sub-types.
            </para>


            <para>Finally, to support annotation (to
               simplify user's development effort), the JBossCache distribution ships with a
               <literal>jboss-aop.xml</literal>
               under the
               <literal>resources</literal>
               directory. When you use the annotation
               precompiler, this file needs to be in the class path. For example,
               please refer to the
               <literal>annoc</literal>
               Ant build target. For
               reference, here is the content of that
               <literal>jboss-aop.xml</literal>
               :
<programlisting>
&lt;aop&gt;
  &lt;prepare expr="field(* @@org.jboss.cache.aop.AopMarker-&gt;*)" /&gt;
  &lt;prepare expr="field(* $instanceof{@@org.jboss.cache.aop.InstanceOfAopMarker}-&gt;*)" /&gt;
&lt;/aop&gt;
</programlisting>
               Basically, it simply states that any annotation
               with both marker interfaces will be "aspectized" accordingly.
            </para>


            <para>Here is two code snippets that illustrate the declaration of
               both types through 1.4 style annotation:</para>


<programlisting>
/**
* @@org.jboss.cache.aop.AopMarker
*/
public class Address {...}
</programlisting>

The above declaration will instrument the class <literal>Address</literal>, and

<programlisting>
/**
* @@org.jboss.cache.aop.InstanceOfAopMarker
*/
public class Person {...}
</programlisting>
The above declaration will instrument the class <literal>Person</literal> and all of its sub-classes. That is, if
<literal>Student</literal> sub-class from <literal>Personal</literal>, then it will get instrumented automatically without
            further annotation declaration.


            <para>Note that the simplicity of declaring POJOs through annotation
               and its marker interfaces (although you will need to use the
               annotation pre-compiler.) See the build.xml target
               <code>annoc</code>
               for example.
            </para>
</sect2>

            <sect2>
               <title>JDK5.0</title>
               <para>The JDK5.0 annotation is similar to the JDK1.4 counterpart except the annotation names themselves
               are different, e.g., the two annotations are:
                  <code>@org.jboss.cache.aop.annotation.PojoCacheable</code>
                  and
                  <code>@org.jboss.cache.aop.annotation.InstanceOfPojoCacheable.</code>
                  For example, when using JDK5.0 annotation, instead of using <code>@@org.jboss.cache.aop.AopMarker</code>
                   you will use <code>@org.jboss.cache.aop.annotation.PojoCacheable</code> instead. In the distribution, under
                  <code>examples/PojoCache/annotated50</code>, there is an example of using JDK50 annotation. Note that we have
                  decided to use different annotation naming convention between JDK1.4 and 5.0.
               </para>
            </sect2>

            <sect2>
               <title>JDK5.0 field level annotations</title>
               <para>In Release 1.4, we have added two additional field level annotations for customized behavior.
                  The first one is <code>@org.jboss.cache.aop.annotation.Transient</code>. When applied to a field
                  variable, it has the same effect as the Java language <code>transient</code> keyword. That is, PojoCache
                  won't put this field into cache management (and therefore no replication).
               </para>
               <para>
                  The second one is <code>@org.jboss.cache.aop.annotation.Serializable</code>, when applied to a field
                  varaiable, PojoCache will treat this variable as <code>Serializable</code>, even when it is
                  <code>PojoCacheable</code>. However, the field will need to implement the <code>Serializable</code>
                  interface such that it can be replicated.
               </para>
               <para>Here is a code snippet that illustrates usage of these two annotations.
                  Assuming that you have a Gadget class:
<programlisting>
public class Gadget
{
   // resource won't be replicated
   @Transient Resource resource;
   // specialAddress is treated as a Serializable object but still has object relationship
   @Serializable SpecialAddress specialAddress;
   // other state variables
}
</programlisting>
               Then when we do:
<programlisting>
   Gadget gadget = new Gadget();
   Resource resource = new Resouce();
   SepcialAddress specialAddress = new SpecialAddress();

   // setters
   gadget.setResource(resource);
   gadget.setSpecialAddress(specialAddress);

   cache1.putObject("/gadget", gadget); // put into PojoCache management

   Gadget g2 = (Gadget)cache2.getObject("/gadget"); // retrieve it from another cache instance
   g2.getResource(); // This is should be null becuase of @Transient tag so it is not replicated.

   SepcialAddress d2 = g2.getSpecialAddress();
   d2.setName("inet"); // This won't get replicated automatically because of @Serializable tag
   ge.setSpecialAddress(d2); // Now this will.
</programlisting>
               </para>
            </sect2>

         </sect1>

         <sect1>
            <title>Weaving</title>

            <para>As already mentioned, a user can use the aop precompiler
               (<literal>aopc</literal>) to precompile the POJO classes such that,
               during runtime, there is no additional system class loader needed. The
               precompiler will read in
               <literal>jboss-aop.xml</literal>
               and weave
               the POJO byte code at compile time. This is a convenient feature to
               make the aop less intrusive.
            </para>
            <para>
               Below is an Ant snippet that defines the library needed for the various Ant targets that we are
               listing here. User can refer to the <literal>build.xml</literal> in the distribution for full details.
<programlisting>
   &lt;path id="aop.classpath"/&gt;
       &lt;fileset dir="${lib}"/&gt;
          &lt;include name="**/*.jar" //&gt;
          &lt;exclude name="**/jboss-cache.jar" //&gt;
          &lt;exclude name="**/j*unit.jar" //&gt;
          &lt;exclude name="**/bsh*.jar" //&gt;
       &lt;/fileset/&gt;
   &lt;/path/&gt;
</programlisting>
            </para>

         <sect2>
            <title>Ant target for running load-time instrumentation using specialized class loader</title>
            <para>Below is the code snippet for the Ant target that is doing loadtime instrumentation through a special
               classloader. Basically, the Ant target <literal>one.test.aop</literal> using the bootclass loader generated
               by the Ant target <literal>generateClassLoader</literal> to run an individual test.
               Note that since JBossAop 1.3, a new <literal>GenerateInstrumentedClassLoader</literal>
            has been used since the previous <literal>SystemClassLoader</literal> is error prone.</para>
<programlisting>
   &lt;target name="generateClassLoader" description=
           "Generate a new modified class loader so we can perform load time instrumentation"&gt;
      &lt;property name="build.bootclasspath" value="${output}/gen-bootclasspath"/&gt;
      &lt;java classname="org.jboss.aop.hook.GenerateInstrumentedClassLoader"&gt;
         &lt;classpath&gt;
            &lt;path refid="aop.classpath"/&gt;
         &lt;/classpath&gt;
         &lt;arg value="${build.bootclasspath}"/&gt;
      &lt;/java&gt;
      &lt;path id="bootclasspath"&gt;
         &lt;pathelement location="${build.bootclasspath}"/&gt;
         &lt;path refid="aop.classpath"/&gt;
      &lt;/path&gt;
      &lt;property name="bootclasspath" refid="bootclasspath"/&gt;
   &lt;/target&gt;

   &lt;!-- eg. ant run.examples -Dtest=org.jboss.test.cache.test.local.NoTxUnitTestCase --&gt;
   &lt;target name="one.test.aop" depends="compile, generateClassLoader" description="run one junit test case."&gt;
      &lt;junit printsummary="yes" timeout="${junit.timeout}" fork="yes"&gt;
         &lt;jvmarg value="-Djboss.aop.path=${output}/etc/META-INF/jboss-aop.xml"/&gt;
         &lt;jvmarg value="-Xbootclasspath/p:${bootclasspath}"/&gt;
         &lt;!-- jvmarg value="-Dbind.address=${bind.address}"/ --&gt;
         &lt;classpath path="${output}/etc" /&gt;
         &lt;sysproperty key="log4j.configuration" value="file:${output}/etc/log4j.xml" /&gt;
         &lt;classpath refid="lib.classpath"/&gt;
         &lt;classpath path="${build}"/&gt;
         &lt;formatter type="xml" usefile="true"/&gt;
         &lt;test name="${test}" todir="${reports}"/&gt;
      &lt;/junit&gt;
  &lt;/target&gt;   
</programlisting>
            <para>
               If you are running JDK5.0, you can also use the <code>javaagent</code> option that does not require a
               separate Classloader. Here are the ant snippet from <code>one-test-aop50</code>, for example.
<programlisting>
   &lt;target name="one.test.aop50" depends="compile, generateClassLoader" description="run one junit test case."&gt;
     &lt;junit printsummary="yes" timeout="${junit.timeout}" fork="yes"&gt;
        &lt;jvmarg value="-Djboss.aop.path=${output}/resources/jboss-aop.xml"/&gt;
        &lt;jvmarg value="-javaagent:${lib-50}/jboss-aop-jdk50.jar"/&gt;
        &lt;classpath path="${output}/etc" /&gt;
        &lt;sysproperty key="log4j.configuration" value="file:${output}/etc/log4j.xml" /&gt;
        &lt;classpath refid="lib.classpath.50"/&gt;
        &lt;classpath refid="build.classpath.50"/&gt;
        &lt;formatter type="xml" usefile="true"/&gt;
        &lt;test name="${test}" todir="${reports}"/&gt;
     &lt;/junit&gt;
   &lt;/target&gt;
</programlisting>
            </para>
         </sect2>

         <sect2>
            <title>Ant target for aopc</title>
            <para>Below is the code snippet for the <literal>aopc</literal> Ant target. Running this target will do
            compile-time weaving of the POJO classes specified.</para>
<programlisting>
   &lt;taskdef name="aopc" classname="org.jboss.aop.ant.AopC" classpathref="aop.classpath"/&gt;
   &lt;target name="aopc" depends="compile" description="Precompile aop class"&gt;
      &lt;aopc compilerclasspathref="aop.classpath" verbose="true"&gt;
         &lt;src path="${build}"/&gt;
         &lt;include name="org/jboss/cache/aop/test/**/*.class"/&gt;
         &lt;aoppath path="${output}/etc/META-INF/jboss-aop.xml"/&gt;
         &lt;classpath path="${build}"/&gt;
         &lt;classpath refid="lib.classpath"/&gt;
      &lt;/aopc&gt;
   &lt;/target&gt;
</programlisting>
            <para>
               Below is a snapshot of files that are generated when aopc is applied. Notice that couple extra classes have
               been generated because of <literal>aopc</literal>.
            </para>
            <figure>
               <title>Classes generated after aopc</title>

               <mediaobject>
                  <imageobject>
                     <imagedata fileref="images/classes.png"/>
                  </imageobject>
               </mediaobject>
            </figure>

         </sect2>

         <sect2>
            <title>Ant target for annotation compiler</title>
            <para>Below is the code snippet for the <literal>annoc</literal> Ant target. You run this step if you are using
            the JDK1.4 annotation. After this step is successfully run, you decide either to use compile-time or load-time mode
            of weaving.</para>
<programlisting>
   &lt;!-- pre-compile directory with annotationc using jdk1.4 --&gt;
   &lt;target name="annoc" depends="compile" description="Annotation precompiler for aop class"&gt;
      &lt;!-- Define a new ant target. This is the 1.4 annotation pre-compiler. After running this step,
           you still need to run the aopc step again, if you are not using system class loader.
      --&gt;
       &lt;taskdef name="annotationc" classname="org.jboss.aop.ant.AnnotationC" classpathref="aop.classpath"/&gt;
       &lt;annotationc compilerclasspathref="aop.classpath" bytecode="true"&gt;
          &lt;classpath refid="lib.classpath"/&gt;
          &lt;classpath path="${build}"/&gt;
          &lt;!--System wide jboss-aop.xml is located here. --&gt;
          &lt;classpath path="${output.resources.dir}"/&gt;
          &lt;src path="${source}"/&gt;
          &lt;include name="org/jboss/cache/aop/test/**/*.java"/&gt;
       &lt;/annotationc&gt;
   &lt;/target&gt;
</programlisting>
         </sect2>
         </sect1>


</chapter>
