Author: jason.greene(a)jboss.com
Date: 2007-11-26 13:15:30 -0500 (Mon, 26 Nov 2007)
New Revision: 4775
Modified:
pojo/trunk/src/main/docbook/userguide/en/modules/instrumentation.xml
pojo/trunk/src/test/java/org/jboss/cache/pojo/rollback/ListUndoTest.java
pojo/trunk/src/test/java/org/jboss/cache/pojo/rollback/LocalUndoTest.java
pojo/trunk/src/test/java/org/jboss/cache/pojo/rollback/MapUndoTest.java
pojo/trunk/src/test/java/org/jboss/cache/pojo/rollback/SetUndoTest.java
Log:
Merge 4774 from 2.1 branch
Modified: pojo/trunk/src/main/docbook/userguide/en/modules/instrumentation.xml
===================================================================
--- pojo/trunk/src/main/docbook/userguide/en/modules/instrumentation.xml 2007-11-26
18:14:21 UTC (rev 4774)
+++ pojo/trunk/src/main/docbook/userguide/en/modules/instrumentation.xml 2007-11-26
18:15:30 UTC (rev 4775)
@@ -1,320 +1,302 @@
+<?xml version="1.0" encoding="UTF-8"?>
<chapter id="instrumentation">
+ <title>Instrumentation</title>
- <title>Instrumentation</title>
+ <para>In order to store an object in POJO Cache, it must be either
+ instrumented or made serializable. Instrumentation is the most optimal
+ approach since it preserves object identity and provides field granular
+ replication. POJO Cache currently uses the JBoss AOP project to provide
+ instrumentation, so the same processes described in the AOP documentation
+ can be used with POJO Cache.</para>
- <para>In this chapter, we explain how to instrument (or
"aspectize") the
- POJOs via JBoss Aop. There are two steps needed by JBoss Aop: 1) POJO
- declaration, 2) instrumentation. But depends on the instrumentation
- mode that you are using, you may not need to pre-process your POJO at all. That
is,
- if you use JDK5.0 (required) and load-time mode, then all you need to do is
- annotating your POJO (or declare it in a xml file). This makes your PojoCache
- programming nearly transparent.</para>
+ <para>The primary input to JBoss AOP is the AOP binding file, which is
+ responsible for specifying which classes should be instrumented. POJO Cache
+ provides a binding file, <literal>pojocache-aop.xml</literal> , which
+ matches all classes that have been annotated with the
+ <literal>@Replicable</literal> annotation. Advanced users may choose to
+ alter this definition to instrument classes in other various interesting
+ ways. However, it is recommended to just stick with the default annotation
+ binding.</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.</para>
+ <para>The instrumentation process can be executed at either load-time, or
+ compile-time. Load-time instrumentation uses a Java agent to intercept and
+ modify classes as they are loaded; whereas compile-time instrumentation
+ requires running <literal>aopc</literal> as part of the compilation
+ process.</para>
- <para>As for the second step, either we can ask JBoss Aop to do load-time
- (through a special class loader, so-called load-time mode) or compile-time
- instrumentation (use of an aopc pre-compiler, so-called precompiled
- mode). Reader can read the JBoss Aop introduction chapter for more
details.</para>
+ <note>
+ <para>Load-time is the recommended approach, since compile-time
+ instrumentation adds hard dependencies to the weaved bytecode which ties
+ the output to a particular version of JBoss AOP.</para>
+ </note>
- <sect1>
- <title>XML descriptor</title>
+ <sect1>
+ <title>Load-time instrumentation</title>
- <para>To declare a POJO via XML configuration file, you will need a
- <literal>META-INF/jboss-aop.xml</literal> (or in the PojoCache
case, it is
- the equivalent <literal>pojocache-service.xml</literal>
- file located under the class
- path or listed in the <literal>jboss.aop.path</literal>
system
- property. JBoss AOP 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. JBoss Aop
- 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 parlance). 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>Load-time instrumentation uses a Java agent to intercept all classes
+ loaded by the JVM. As they are loaded JBoss AOP instruments them, allowing
+ POJO Cache to monitor field changes. To enable load time instrumentation
+ the JVM must be started with the following specified:</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 JBoss Aop.</para>
+ <orderedlist>
+ <listitem>
+ <para>The <literal>jboss.aop.path</literal> system property set
to the
+ location of <literal>pojocache-aop.xml</literal></para>
+ </listitem>
- <para>The standalone
- <literal>JBoss Cache</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>pojocache-aop.xml</literal>
- :
- </para>
+ <listitem>
+ <para>A javaagent argument which includes
+ <emphasis>jboss-aop-jdk50.jar</emphasis></para>
+ </listitem>
+ </orderedlist>
-<programlisting>
-<aop>
- <prepare expr="field(*
$instanceof{(a)org.jboss.cache.pojo.annotation.Replicable}-&gt;*)" />
-</aop>
-</programlisting>
- and then notice the annotation @Replicable used in the
<literal>Person</literal> and
- <literal>Address</literal> POJOs. Also note that @Replicable is
now inheritant. For example,
- sub-class of <literal>Person</literal> such as
<literal>Student</literal> will also
- be aspectized by JBoss Aop as well. If you want to stop this inheritance
behavior,
- you can simply remove the
- <literal>$instanceof</literal> declaration in the prepare
statement, e.g.,
- <programlisting>
- <aop>
- <prepare expr="field(*
@org.jboss.cache.pojo.annotation.Replicable->*)" />
- </aop>
- </programlisting>
+ <para>These requirements lead to the following example ant task:</para>
+ <programlisting><java classname="Foo"
fork="yes">
+ <jvmarg value="-javaagent:lib/jboss-aop.jar"/>
+ <jvmarg
value="-Djboss.aop.path=etc/META-INF/pojocache-aop.xml"/>
+ <classpath refid="test.classpath"/>
+</java> </programlisting>
+ </sect1>
- <para>Detailed semantics of
- <literal>pojocache-aop.xml</literal> (or equivalently
<literal>pojocache-aop.xml</literal>)
- can again
- be found in JBoss Aop. 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>
+ <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.</para>
- <itemizedlist>
- <listitem>
- The wildcard at the end of the expression signifies all fields in the
POJO
- </listitem>
+ <para>As for the second step, either we can ask JBoss Aop to do load-time
+ (through a special class loader, so-called load-time mode) or compile-time
+ instrumentation (use of an aopc pre-compiler, so-called precompiled mode).
+ Reader can read the JBoss Aop introduction chapter for more details.</para>
- <listitem>
- You can potentially replace specific class name with wildcard that
includes all the POJOs inside the
- same package space
- </listitem>
+ <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> (or in the PojoCache case, it is
+ the equivalent <literal>pojocache-service.xml</literal> file located under
+ the class path or listed in the <literal>jboss.aop.path</literal> system
+ property. JBoss AOP 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. JBoss Aop 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 parlance). 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 JBoss Aop. </para> <para> The standalone
+ <literal>JBoss Cache</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>pojocache-aop.xml</literal> : </para>
<programlisting>
+ <aop> <prepare expr="field(*
+ $instanceof{(a)org.jboss.cache.pojo.annotation.Replicable}-&gt;*)"
+ /> </aop>
+ </programlisting> and then notice the annotation @Replicable used in the
+ <literal>Person</literal> and <literal>Address</literal> POJOs.
Also note
+ that @Replicable is now inheritant. For example, sub-class of
+ <literal>Person</literal> such as <literal>Student</literal>
will also be
+ aspectized by JBoss Aop as well. If you want to stop this inheritance
+ behavior, you can simply remove the <literal>$instanceof</literal>
+ declaration in the prepare statement, e.g., <programlisting>
+ <aop> <prepare expr="field(*
+ @org.jboss.cache.pojo.annotation.Replicable->*)" />
+ </aop>
+ </programlisting> <para> Detailed semantics of
+ <literal>pojocache-aop.xml</literal> (or equivalently
+ <literal>pojocache-aop.xml</literal> ) can again be found in JBoss Aop.
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>
- The
+ <listitem>You can potentially replace specific class name with wildcard
+ that includes all the POJOs inside the same package space</listitem>
- <code>instanceof</code>
+ <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>
- 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 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>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>
- <listitem>
- We don't intercept field modifiers of
- <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>
- <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.</para>
+ <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.</para>
- <sect2>
- <title>POJO annotation for instrumentation</title>
- <para>To support annotation (in order to
- simplify user's development effort), the JBoss Cache distribution
ships with a
- <literal>pojocache-aop.xml</literal>
- under the
- <literal>resources</literal>
- directory. For
- reference, here is annotation definition from
- <literal>pojocache-aop.xml</literal> again
- :
-<programlisting>
-<aop>
- <prepare expr="field(*
@org.jboss.cache.pojo.annotation.Replicable->*)" />
-</aop>
-</programlisting>
- Basically, it simply states that any annotation
- with both marker interfaces will be "aspectized" accordingly.
- </para>
+ <sect2><title>POJO annotation for instrumentation</title>
<para> To
+ support annotation (in order to simplify user's development effort), the
+ JBoss Cache distribution ships with a
<literal>pojocache-aop.xml</literal>
+ under the <literal>resources</literal> directory. For reference, here is
+ annotation definition from <literal>pojocache-aop.xml</literal> again :
+ <programlisting>
+ <aop> <prepare expr="field(*
+ @org.jboss.cache.pojo.annotation.Replicable->*)"
+ /> </aop>
+ </programlisting> Basically, it simply states that any annotation
+ with both marker interfaces will be "aspectized" accordingly.
</para>
+ <para> Here is a code snippet that illustrate the declaration: </para>
+ <programlisting>
+ @org.jboss.cache.pojo.annotation.Replicable 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.</sect2>
+ <sect2>
+ <title>JDK5.0 field level annotations</title>
- <para>Here is a code snippet that illustrate the
declaration:</para>
-<programlisting>
-(a)org.jboss.cache.pojo.annotation.Replicable
-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.
- </sect2>
+ <para>In Release 2.0, we have added two additional field level
+ annotations for customized behavior. The first one is
+ <code>(a)org.jboss.cache.pojo.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>
- <sect2>
- <title>JDK5.0 field level annotations</title>
- <para>In Release 2.0, we have added two additional field level
annotations for customized behavior.
- The first one is
<code>(a)org.jboss.cache.pojo.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>(a)org.jboss.cache.pojo.annotation.Serializable</code>, when applied to a
field
- variable, PojoCache will treat this variable as
<code>Serializable</code>, even when it is
- <code>Replicable</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 Resource();
- SepcialAddress specialAddress = new SpecialAddress();
+ <para>The second one is <code>
+ @org.jboss.cache.pojo.annotation.Serializable </code> , when applied to
+ a field variable, PojoCache will treat this variable as
+ <code>Serializable</code> , even when it is
<code>Replicable</code> .
+ However, the field will need to implement the
<code>Serializable</code>
+ interface such that it can be replicated.</para>
- // setters
- gadget.setResource(resource);
- gadget.setSpecialAddress(specialAddress);
+ <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 Resource(); SepcialAddress specialAddress = new
+ SpecialAddress();
- cache1.putObject("/gadget", gadget); // put into PojoCache management
+ // setters gadget.setResource(resource);
+ gadget.setSpecialAddress(specialAddress);
- Gadget g2 = (Gadget)cache2.getObject("/gadget"); // retrieve it from another
cache instance
- g2.getResource(); // This is should be null because of @Transient tag so it is not
replicated.
+ cache1.putObject("/gadget", gadget); // put into
+ PojoCache management
- 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>
+ Gadget g2 = (Gadget)cache2.getObject("/gadget"); //
+ retrieve it from another cache instance
+ g2.getResource(); // This is should be null because
+ of @Transient tag so it is not replicated.
- </sect1>
+ 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>
+ <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>pojocache-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>
- <path id="aop.classpath"/>
- <fileset dir="${lib}"/>
- <include name="**/*.jar" //>
- <exclude name="**/jboss-cache.jar" //>
- <exclude name="**/j*unit.jar" //>
- <exclude name="**/bsh*.jar" //>
- </fileset/>
- </path/>
-</programlisting>
- </para>
+ <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>pojocache-aop.xml</literal> and weave
+ the POJO byte code at compile time. This is a convenient feature to make
+ the aop less intrusive.</para>
- <sect2>
- <title>Ant target for running load-time instrumentation using
specialized class loader</title>
- <para>
- In JDK5.0, you can use the <code>javaagent</code> option that
does not require a
- separate Classloader. Here are the ant snippet from
<code>one-test-pojo</code>, for example.
-<programlisting>
- <target name="one.test.pojo" depends="compile"
description="run one junit test case.">
- <junit printsummary="yes" timeout="${junit.timeout}"
fork="yes">
- <jvmarg
value="-Djboss.aop.path=${output}/resources/pojocache-aop.xml"/>
- <jvmarg value="-javaagent:${lib}/jboss-aop-jdk50.jar"/>
- <classpath path="${output}/etc" />
- <sysproperty key="log4j.configuration"
value="file:${output}/etc/log4j.xml" />
- <classpath refid="lib.classpath"/>
- <classpath refid="build.classpath"/>
- <formatter type="xml" usefile="true"/>
- <test name="${test}" todir="${reports}"/>
- </junit>
- </target>
-</programlisting>
- </para>
- </sect2>
+ <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>
+ <path id="aop.classpath"/> <fileset
+ dir="${lib}"/> <include name="**/*.jar"
//>
+ <exclude name="**/jboss-cache.jar" //>
<exclude
+ name="**/j*unit.jar" //> <exclude
+ name="**/bsh*.jar" //> </fileset/>
+ </path/>
+ </programlisting></para>
- <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>
- <taskdef name="aopc" classname="org.jboss.aop.ant.AopC"
classpathref="aop.classpath"/>
- <target name="aopc" depends="compile"
description="Precompile aop class">
- <aopc compilerclasspathref="aop.classpath"
verbose="true">
- <src path="${build}"/>
- <include name="org/jboss/cache/aop/test/**/*.class"/>
- <aoppath path="${output}/resources/pojocache-aop.xml"/>
- <classpath path="${build}"/>
- <classpath refid="lib.classpath"/>
- </aopc>
- </target>
-</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>
+ <sect2>
+ <title>Ant target for running load-time instrumentation using
+ specialized class loader</title>
- <mediaobject>
- <imageobject>
- <imagedata fileref="images/classes.png"/>
- </imageobject>
- </mediaobject>
- </figure>
+ <para>In JDK5.0, you can use the <code>javaagent</code> option
that does
+ not require a separate Classloader. Here are the ant snippet from
+ <code>one-test-pojo</code> , for example. <programlisting>
+ <target name="one.test.pojo" depends="compile"
+ description="run one junit test case."> <junit
+ printsummary="yes" timeout="${junit.timeout}"
+ fork="yes"> <jvmarg
+
value="-Djboss.aop.path=${output}/resources/pojocache-aop.xml"/>
+ <jvmarg
+ value="-javaagent:${lib}/jboss-aop-jdk50.jar"/>
+ <classpath path="${output}/etc" />
+ <sysproperty key="log4j.configuration"
+ value="file:${output}/etc/log4j.xml" />
+ <classpath refid="lib.classpath"/>
+ <classpath refid="build.classpath"/>
+ <formatter type="xml" usefile="true"/>
+ <test name="${test}"
todir="${reports}"/>
+ </junit> </target>
+ </programlisting></para>
+ </sect2>
- </sect2>
- </sect1>
+ <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>
-</chapter>
+ <programlisting>
+ <taskdef name="aopc"
+ classname="org.jboss.aop.ant.AopC"
+ classpathref="aop.classpath"/> <target
name="aopc"
+ depends="compile" description="Precompile aop
class">
+ <aopc compilerclasspathref="aop.classpath"
+ verbose="true"> <src
path="${build}"/>
+ <include
+ name="org/jboss/cache/aop/test/**/*.class"/>
+ <aoppath
+ path="${output}/resources/pojocache-aop.xml"/>
+ <classpath path="${build}"/> <classpath
+ refid="lib.classpath"/> </aopc>
</target>
+ </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>
+ </sect1>
+</chapter>
\ No newline at end of file
Modified: pojo/trunk/src/test/java/org/jboss/cache/pojo/rollback/ListUndoTest.java
===================================================================
--- pojo/trunk/src/test/java/org/jboss/cache/pojo/rollback/ListUndoTest.java 2007-11-26
18:14:21 UTC (rev 4774)
+++ pojo/trunk/src/test/java/org/jboss/cache/pojo/rollback/ListUndoTest.java 2007-11-26
18:15:30 UTC (rev 4775)
@@ -33,7 +33,7 @@
*/
@Test(groups = {"functional"})
-public class ListUndoTest
+public class ListUndoTest
{
Log log_ = LogFactory.getLog(ListUndoTest.class);
PojoCache cache_;
@@ -71,7 +71,13 @@
list.add("test1");
setTxRollback(true);
- cache_.attach("/a", list);
+ try
+ {
+ cache_.attach("/a", list);
+ }
+ catch (Exception e)
+ {
+ }
assertFalse("Should not have cache interceptor ", isProxy(list));
cache_.attach("/a", list);
@@ -88,7 +94,13 @@
test.setLanguages(list);
setTxRollback(true);
- cache_.attach("/a", test);
+ try
+ {
+ cache_.attach("/a", test);
+ }
+ catch (Exception e)
+ {
+ }
assertFalse("Should not have cache interceptor ",
isProxy(test.getLanguages()));
cache_.attach("/a", test);
@@ -113,13 +125,15 @@
cache_.attach("/a", test);
setTxRollback(true);
- cache_.detach("/a");
+ try
+ {
+ cache_.detach("/a");
+ }
+ catch (Exception e)
+ {
+ }
assertTrue("Should still have cache interceptor ",
isProxy(test.getLanguages()));
cache_.detach("/a");
}
-
-
-
-
}
Modified: pojo/trunk/src/test/java/org/jboss/cache/pojo/rollback/LocalUndoTest.java
===================================================================
--- pojo/trunk/src/test/java/org/jboss/cache/pojo/rollback/LocalUndoTest.java 2007-11-26
18:14:21 UTC (rev 4774)
+++ pojo/trunk/src/test/java/org/jboss/cache/pojo/rollback/LocalUndoTest.java 2007-11-26
18:15:30 UTC (rev 4775)
@@ -33,7 +33,7 @@
*/
@Test(groups = {"functional"})
-public class LocalUndoTest
+public class LocalUndoTest
{
Log log_ = LogFactory.getLog(LocalUndoTest.class);
PojoCache cache_;
@@ -73,7 +73,13 @@
test.setAge(10);
setTxRollback(true);
- cache_.attach("/a", test);
+ try
+ {
+ cache_.attach("/a", test);
+ }
+ catch (Exception e)
+ {
+ }
assertFalse("Should not have cache interceptor ",
hasCacheInterceptor(test));
}
@@ -97,7 +103,13 @@
cache_.attach("/a", test);
setTxRollback(true);
- cache_.detach("/a");
+ try
+ {
+ cache_.detach("/a");
+ }
+ catch (Exception e)
+ {
+ }
assertTrue("Should still have cache interceptor ",
hasCacheInterceptor(test));
}
Modified: pojo/trunk/src/test/java/org/jboss/cache/pojo/rollback/MapUndoTest.java
===================================================================
--- pojo/trunk/src/test/java/org/jboss/cache/pojo/rollback/MapUndoTest.java 2007-11-26
18:14:21 UTC (rev 4774)
+++ pojo/trunk/src/test/java/org/jboss/cache/pojo/rollback/MapUndoTest.java 2007-11-26
18:15:30 UTC (rev 4775)
@@ -33,7 +33,7 @@
*/
@Test(groups = {"functional"})
-public class MapUndoTest
+public class MapUndoTest
{
Log log_ = LogFactory.getLog(MapUndoTest.class);
PojoCache cache_;
@@ -71,7 +71,13 @@
map.put("1", "test1");
setTxRollback(true);
- cache_.attach("/a", map);
+ try
+ {
+ cache_.attach("/a", map);
+ }
+ catch (Exception e)
+ {
+ }
assertFalse("Should not have cache interceptor ", isProxy(map));
cache_.attach("/a", map);
@@ -88,7 +94,13 @@
test.setHobbies(map);
setTxRollback(true);
- cache_.attach("/a", test);
+ try
+ {
+ cache_.attach("/a", test);
+ }
+ catch (Exception e)
+ {
+ }
assertFalse("Should not have cache interceptor ",
isProxy(test.getHobbies()));
cache_.attach("/a", test);
@@ -113,7 +125,13 @@
cache_.attach("/a", test);
setTxRollback(true);
- cache_.detach("/a");
+ try
+ {
+ cache_.detach("/a");
+ }
+ catch (Exception e)
+ {
+ }
assertTrue("Should still have cache interceptor ",
isProxy(test.getHobbies()));
cache_.detach("/a");
Modified: pojo/trunk/src/test/java/org/jboss/cache/pojo/rollback/SetUndoTest.java
===================================================================
--- pojo/trunk/src/test/java/org/jboss/cache/pojo/rollback/SetUndoTest.java 2007-11-26
18:14:21 UTC (rev 4774)
+++ pojo/trunk/src/test/java/org/jboss/cache/pojo/rollback/SetUndoTest.java 2007-11-26
18:15:30 UTC (rev 4775)
@@ -33,7 +33,7 @@
*/
@Test(groups = {"functional"})
-public class SetUndoTest
+public class SetUndoTest
{
Log log_ = LogFactory.getLog(SetUndoTest.class);
PojoCache cache_;
@@ -71,7 +71,13 @@
set.add("test1");
setTxRollback(true);
- cache_.attach("/a", set);
+ try
+ {
+ cache_.attach("/a", set);
+ }
+ catch (Exception e)
+ {
+ }
assertFalse("Should not have cache interceptor ", isProxy(set));
cache_.attach("/a", set);
@@ -88,7 +94,12 @@
test.setSkills(set);
setTxRollback(true);
- cache_.attach("/a", test);
+ try
+ {
+ cache_.attach("/a", test);
+ } catch (Exception e)
+ {
+ }
assertFalse("Should not have cache interceptor ",
isProxy(test.getSkills()));
cache_.attach("/a", test);
@@ -113,13 +124,14 @@
cache_.attach("/a", test);
setTxRollback(true);
- cache_.detach("/a");
+ try
+ {
+ cache_.detach("/a");
+ } catch (Exception e)
+ {
+ }
assertTrue("Should still have cache interceptor ",
isProxy(test.getSkills()));
cache_.detach("/a");
}
-
-
-
-
}