<chapter id="compiling">

   <title>Building and Compiling Aspectized Java</title>

   <sect1 id="modes" revision="1">
      <title>Instrumentation modes</title>
      <para>
         JBoss AOP works by instrumenting the classes you want to run. This means
         that modifications to the bytecode are made in order to add extra information
         to the classes to hook into the AOP library.  JBoss AOP allows for two types 
         of instrumentation
         <itemizedlist>
            <listitem>
               Precompiled - The classes are instrumented in a separate aop compilation 
               step before they are run.
            </listitem>
            <listitem>
               Loadtime - The classes are instrumented when they are first loaded.
            </listitem>
         </itemizedlist>
         This chapter describes the steps you need to take to precompile your classes 
         with the aop precompiler.
      </para>
   </sect1>

   <sect1 id="ant" revision="1">
      <title>Ant Integration</title>
      <para>
         JBoss AOP comes with an ant task that you can use for precompiling your
         classes with the aop precompiler. An example build.xml file is the basis
         for the explanation. (It is quite similar to the one used in the previous
         chapter.) There will be differences in the build.xml file if you are using
         JDK 1.4.2 or JDK 5.0, these are outlined below:
      </para>
      <para>
         <programlisting><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>

<project default="compile" name="JBoss/AOP">
   <target name="prepare">]]>
         </programlisting>
      </para>
      <para>
         Define the source directory, and the directory to compile classes to.
         If you're not fussy, they can point to the same directory.
         <programlisting><![CDATA[
         <property name="src.dir" value="PATH TO YOUR SOURCE DIR">
         <property name="classes.dir" value="PATH TO YOUR DIR FOR COMPILED CLASSES">]]>
         </programlisting>
      </para>
      <para>
         Include the jars AOP depends on, these are common to all JDK's
         <programlisting><![CDATA[
         <path id="javassist.classpath">
            <pathelement path="../../../javassist.jar"/>
         </path>

         <path id="trove.classpath">
            <pathelement path="../../../trove.jar"/>
         </path>

         <path id="concurrent.classpath">
            <pathelement path="../../../concurrent.jar"/>
         </path>

         <path id="jboss.common.classpath">
            <pathelement path="../../../jboss-common.jar"/>
         </path>

         <path id="lib.classpath">
            <path refid="javassist.classpath"/>
            <path refid="trove.classpath"/>
            <path refid="jboss.aop.classpath"/>
            <path refid="jboss.common.classpath"/>
            <path refid="concurrent.classpath"/>
         </path>]]>
         </programlisting>
      </para>
      <para>
         This snippet shows what to do for JDK 1.4. It will also work with
         JDK 5.0 if your classes do not use JDK 5.0 style annotations and enums:
         <programlisting><![CDATA[
         <!--                  JDK version 1.4.2                         -->
         <!-- Do not include this if using JDK 1.5 with annotations!!!!  -->

         <path id="jboss.aop.classpath">
            <pathelement path="../../../jboss-aop.jar"/>
         </path>

         <!--            JDK version 1.4.2 - END                         -->]]>
         </programlisting>
      </para>
      <para>
         This snippet shows what to do for JDK 5.0 if you are using JDK 5.0 annotations:
         <programlisting><![CDATA[
         <!--            JDK version 1.5                                 -->
         <!-- Do not include this if using JDK 1.4.2!!!!                 -->

         <path id="jboss.aop.classpath">
            <pathelement path="../../../jboss-aop-jdk15.jar"/>
         </path>

         <!--            JDK version 1.5 - END                           -->]]>
         </programlisting>
   	   (You should only use one of the two previous snippets for setting up
   	   jboss.aop.classpath)
      </para>
      <para>
         Now we set up the full classpath of all the needed libraries:
         <programlisting><![CDATA[
         <path id="classpath">
            <path refid="lib.classpath"/>
            <path refid="jboss.aop.classpath"/>
         </path id="classpath">]]>
         </programlisting>
      </para>
      <para>
         Define the
         <literal>org.jboss.aop.ant.AopC</literal> ant aop precompiler task:
         <programlisting><![CDATA[
         <taskdef name="aopc" classname="org.jboss.aop.ant.AopC"
               classpathref="jboss.aop.classpath"/>
         </target>]]>
         </programlisting>
      </para>
      <para>
         <programlisting><![CDATA[>
            <target name="compile" depends="prepare">]]>
         </programlisting>
      </para>
      <para>
         Compile the files (from the source directory to the compiled classes directory:
         <programlisting><![CDATA[
         <javac srcdir="${src.dir}"
                destdir="${classes.dir}"
                debug="on"
                deprecation="on"
                optimize="off"
                includes="**">
            <classpath refid="classpath"/>
         </javac>]]>
         </programlisting>
      </para>
      <para>
         Now use the ant aop precompiler task, it reads the files from the
         <programlisting><![CDATA[
         <aopc compilerclasspathref="classpath" verbose="true">
            <classpath path="${classes.dir}"/>
            <src path="${classes.dir}"/>
            <include name="**/*.class"/>
            <aoppath path="jboss-aop.xml"/>
            <aopclasspath path="aspects.jar"/>
         </aopc>]]>
         </programlisting>

         If you are using JDK 1.4.2 and wish to use annotations, you need to define the
         <literal>org.jboss.aop.ant.AnnotationC</literal> ant task, and run that BEFORE you
         invoke the
         <literal>org.jboss.aop.ant.AopC</literal> task. How to do this is shown
         in the previous chapter.
      </para>
      <para>
         The
         <literal>org.jboss.aop.ant.AopC</literal> ant task takes several parameters.
      </para>

      <itemizedlist>
         <listitem>
            <literal>compilerclasspath</literal> or
            <literal>compilerclasspathref</literal> -
               These are interchangable, and represent the jars needed for the aop precompiler
               to work. The
            <literal>compilerclasspath</literal> version takes the paths of the
               jar files, and the
            <literal>compilerclasspathref</literal> version takes the
               name of a predefined ant path. They can be specified as attributes of
            <literal>aopc</literal>, as shown above.
            <literal>compilerclasspath</literal> can also be
               specified as a child element of
            <literal>aopc</literal>, in which case you can use
               all the normal ant functionality for paths (e.g. fileset).
         </listitem>
         <listitem>
            <literal>classpath</literal> or
            <literal>classpathref</literal> - Path to the
               compiled classes to be instrumented. The
            <literal>classpath</literal>
               version takes the path of the directory, and the
            <literal>classpathref</literal>
               version takes the name of a predefined ant path. They both be specified as attributes
               of
            <literal>aopc</literal>.
            <literal>classpath</literal> can also be
               specified as a child element of
            <literal>aopc</literal>, as shown above, in which case
               you can use all the normal ant functionality for paths (e.g. fileset). The full classpath
               of the underlying java process will be classpath + compilerclasspath.
         </listitem>
         <listitem>
            <literal>src</literal> - A directory containing files to be transformed. <!--Either a directory containing
               the files to be instrumented, or an ant fileset containing which files should be precompiled.
               In the example above, we specified a directory so all our classes are passed in to the
               precompiler.--> You can use multiple src elements to specify more that one root directory for transformation.
         </listitem>
         <listitem>
            <literal>include</literal> - This is optional and it serves as a filter
            to pick out which files within <literal>src</literal> should be transformed. You can use wildcards within the
            <literal>name</literal> expression, and you can also use multiple <literal>include</literal> elements.
         </listitem>
         <listitem>
            <literal>verbose</literal> - Default is false. If true, verbose output
               is generated, which comes in handy for diagnosing unexpected results.
         </listitem>
         <listitem>
            <literal>report</literal> - Default is false. If true, the classes are not
               instrumented, but a report called
            <literal>aop-report.xml</literal> is generated
               which shows all classes that have been loaded that pertain to AOP, what interceptors
               and advices that are attached, and also what metadata that has been attached. One
               particularly useful thing is the unbounded section. It specifys all bindings
               that are not bound. It allows you to debug when you might have a typo in one of your
               XML deployment descriptors.
               <para/>
               Report generation works on the instrumented classes, so to get valid data in your
               report, you have to to make two passes with <literal>aopc</literal>. First 
               you run <literal>aopc</literal> with <literal>report="false"</literal> to 
               instrument the classes, and then you run <literal>aopc</literal> with 
               <literal>report="true"</literal> to generate the report.
         </listitem>
         <listitem>
            <literal>aoppath</literal> - The path of the
            <literal>*-aop.xml</literal> file containing
               the xml configuration of your bindings. Files or Directories can be specified.
            If it is a directory, JBoss AOP will take all
            <literal>aop.xml</literal> files from that directory.
               This gets used for the
            <literal>jboss.aop.path</literal>
               optional system property which is described in the "Command Line" section. If you have more
               than one xml file, for example if you have both a "normal"
            <literal>jboss-aop.xml</literal>
               file, and a
            <literal>metadata-aop.xml</literal> file having used the JDK 1.4.2 annotation
               compiler, you can specify these as follows:
            <programlisting>
               &lt;aoppath&gt;
               &lt;pathelement path="jboss-aop.xml"/&gt;
               &lt;pathelement path="metadata-aop.xml"/&gt;
               &lt;pathelement path="xmldir"/&gt;
               &lt;/aoppath&gt;
            </programlisting>
         </listitem>
         <listitem>
            <literal>aopclasspath</literal> - This should mirror your class path and contain all JARs/directories
               that may have annotated aspects (Ses Chapter "Annotated Bindings").  The AOPC compiler will browser
               each class file in this path to determine if any of them are annotationed with
            <literal>@Aspect</literal>.
               This gets used for the
            <literal>jboss.aop.class.path</literal>
               optional system property which is described in the "Command Line" section. If you have more
               than one jar file, you can specify these as follows:
            <programlisting>
               &lt;aopclasspath&gt;
               &lt;pathelement path="aspects.jar"/&gt;
               &lt;pathelement path="foo.jar"/&gt;
               &lt;/aopclasspath&gt;
            </programlisting>
         </listitem>
         <listitem>
            <literal>maxsrc</literal> - The ant task expands any directories in 
               <literal>src</literal> to list all class files, when creating the parameters
               for the java command that actually performs the compilation. On some operating
               systems there is a limit to the length of vaid command lines. The default value 
               for <literal>maxsrc</literal> is 1000. If the total length of all the files used
               is greater than <literal>maxsrc</literal>, a temporary file listing the files
               to be transformed is used and passed in to the java command instead. If you have 
               problems running the <literal>aopc</literal> task, try setting this value to 
               a value smaller than 1000.
          </listitem>
      </itemizedlist>
   </sect1>

   <sect1 id="commandline" revision="1">
      <title>Command Line</title>
      <para>
            To run the aop precompiler from the command line you need all the aop jars on your classpath, and
            the class files you are instrumenting must have everything they would need to run in the java
            classpath, including themselves, or the precompiler will not be able to run.
      </para>
      <para>
         The
         <literal>jboss.aop.path</literal> optional system property points to XML files that contain your
            pointcut, advice bindings, and metadata definitions that the precompiler will use to instrument
            the .class files. The property can have one or files it points to delimited by the operating
            systems specific classpath delimiter (';' on windows, ':' on unix).  Files or Directories can be specified.
            If it is a directory, JBoss AOP will take all
         <literal>aop.xml</literal> files from that directory.
      </para>

      <para>
         The
         <literal>jboss.aop.class.path</literal> optional system property points to all JARs or directories that
            may have classes that are annotated as
         <literal>@Aspect</literal> (See Chapter "Annotated Bindings").
            JBoss AOP will browse all classes in this path to see if they are annotated.
            The property can have one or files it points to delimited by the operating
            systems specific classpath delimiter (';' on windows, ':' on unix). Note for this to
            have effect with JDK 1.4, you first have to run the annotation compiler with 
            bytecode=true.
      </para>
      <para>
            It is invoked as:
         <programlisting>
$java -classpath ... [-Djboss.aop.path=...] [-Djboss.aop.class.path=...] \
                     org.jboss.aop.standalone.Compiler &lt;class files or directories&gt;
         </programlisting>
      </para>

      <para>
         In the /bin folder of the distribution we have provided batch/script files to make
         this easier. It includes all the aop libs for you, so you just have to worry
         about your files. The usage for JDK 1.4 is:
         <programlisting>
$ aopc &lt;classpath&gt; [-aoppath ...] [-aopclasspath ...] [-report] [-verbose] \
      &lt;class files or directories&gt;+
         </programlisting>
         And for JDK 1.5:
         <programlisting>
$ aopc15 &lt;classpath&gt; [-aoppath ...] [-aopclasspath ...] [-report] [-verbose] \
      &lt;class files or directories&gt;+
         </programlisting>
      </para>
      <para>         
         <itemizedlist>
            <listitem>
               <literal>classpath</literal> - path to your classes and any jars your code depends on
            </listitem>
         </itemizedlist>
         The other parameters are the same as above.
      </para>

   </sect1>


</chapter>

