Mixins are definitely a good start, but nevertheless it's very hard, because I have to 
split the aspect into the static (mixin) and the dynamic part (interception). My 
feelings about this are that this is not in the spirit of AOP.

But let's get to the facts. As far as I understand the WIKI aspect example, I have to 
it this way:

Write an interface
  | Write an implementation of the interface (mixin)
  | Write two interceptor classes (aspects)
  | 
  | Here we go; First of all the interface:
  | public interface IStackHeight
  |   | {
  |   |     public int size ();
  |   | }
  | 
  | Next comes the mixin. Here I am doing a cheap trick. I need the implementation of 
the size method in order to satisfy the compiler, but later on, I will use an around 
advice so this gets never executed; Dull dummy code.
  | 
  | public class StackHeight implements IStackHeight
  |   | {
  |   |    public int size ()
  |   |    {
  |   |       return 0;
  |   |    }
  |   | }
  | 
  | The StackHeightAspect class. The implementation is similar to the wiki:
  | 
  | import org.jboss.aop.joinpoint.*;
  |   | 
  |   | public class StackHeightAspect
  |   | {
  |   |     private int height;
  |   | 
  |   |     public Object pushInvocation ( MethodInvocation invocation ) throws 
Throwable
  |   |     {
  |   |         ++ this.height;
  |   |         return invocation.invokeNext();
  |   |     }
  |   | 
  |   |     public Object popInvocation ( MethodInvocation invocation ) throws 
Throwable
  |   |     {
  |   |         if ( this.height > 0 )
  |   |         {
  |   |             -- this.height;
  |   |         }
  |   | 
  |   |         return invocation.invokeNext();
  |   |     }
  |   | 
  |   |     public int sizeInvocation ( MethodInvocation invocation ) throws Throwable
  |   |     {
  |   |         return this.height;
  |   |     }
  |   | }
  | 
  | Everyone should see the cheap trick I am doing here, the actual implementation of 
the size method is here, not in the mixin! Apart from that I am not sure if the chosen 
return type, int, is correct. But how would have been the implementation if I am to 
return an Object?
  | 
  | Now the last part, the synchronization aspect, should be straight forward, but I 
have my problems here, too:
  | 
  | import org.jboss.aop.joinpoint.*;
  |   | 
  |   | public class StackSynchronizationAspect
  |   | {
  |   |     private boolean semaphore = false;
  |   | 
  |   |     public Object synchronize ( MethodInvocation invocation ) throws Throwable
  |   |     {
  |   |         // synchronized ( invocation.getInstance () )
  |   |         synchronized ( this )
  |   |         {
  |   |             if ( this.semaphore == true )
  |   |             {
  |   |                 try {
  |   |                     this.wait ();
  |   |                 } catch(InterruptedException e) {}
  |   | 
  |   |                 this.semaphore = true;
  |   |             }
  |   |         }
  |   | 
  |   |         Object result = invocation.invokeNext();
  |   | 
  |   |         // synchronized ( invocation.getInstance () )
  |   |         synchronized ( this )
  |   |         {
  |   |             this.semaphore = false;
  |   | 
  |   |             this.notify ();
  |   |         }
  |   | 
  |   |         return result;
  |   |     }
  |   | }
  | 
  | I want to express in the synchronized statements that the synchronization is about 
the instance of the message receiver. That's what invocation.getInstance should 
indicate. How is this expressed? Surely somehow with context information, but the docs 
are very sparse about that.
  | 
  | Now let's put the pieces together:
  | <?xml version="1.0" encoding="UTF-8"?>
  |   | <aop>
  |   |    <aspect class="StackHeightAspect" scope="PER_INSTANCE"/>
  |   |    <aspect class="StackSynchronizationAspect" scope="PER_INSTANCE"/>
  |   | 
  |   |    <introduction class="Stack">
  |   |       <mixin>
  |   |          <interfaces>
  |   |             IStackHeight
  |   |          </interfaces>
  |   |          <class>StackHeight</class>
  |   |       </mixin>
  |   |    </introduction>
  |   | 
  |   |    <pointcut name="pushExecution" expr="execution(void Stack->push(Object))" />
  |   |    <pointcut name="popExecution" expr="execution(Object Stack->pop())" />
  |   |    <pointcut name="sizeExecution" expr="execution(int Stack->size())" />
  |   | 
  |   |    <bind pointcut="popExecution">
  |   |       <advice name="popInvocation" aspect="StackHeightAspect"/>
  |   |    </bind>
  |   | 
  |   |    <bind pointcut="pushExecution OR popExecution OR sizeExecution">
  |   |       <advice name="synchronize" aspect="StackHeightAspect"/>
  |   |    </bind>
  |   | 
  |   |    <bind pointcut="pushExecution">
  |   |       <advice name="pushInvocation" aspect="StackHeightAspect"/>
  |   |    </bind>
  |   | 
  |   |    <bind pointcut="sizeExecution">
  |   |       <advice name="sizeInvocation" aspect="StackHeightAspect"/>
  |   |    </bind>
  |   | </aop>
  | 
  | This is my test driver (synchronization is not tested here):
  | public class Driver
  |   | {
  |   |     public static void main ( String args [] ) throws Exception
  |   |     {
  |   |         Stack s = new Stack ();
  |   | 
  |   |         Driver.printHeight ( s );
  |   | 
  |   |         s.push ( new Integer ( 5 ) );
  |   |         Driver.printHeight ( s );
  |   | 
  |   |         s.push ( new Integer ( 5 ) );
  |   |         s.pop ();
  |   |         Driver.printHeight ( s );
  |   |     }
  |   | 
  |   |     private static void printHeight ( Stack s ) throws Exception
  |   |     {
  |   |         try
  |   |         {
  |   |             System.out.println ( "Stack size: " + ( (IStackHeight) s ).size () 
);
  |   |         }
  |   |         catch ( Exception e )
  |   |         {
  |   |             System.err.println ( "Introduction failed: " + e );
  |   |         }
  |   |     }
  |   | }
  | 
  | These are the results of my test run:
  | 
  | [EMAIL PROTECTED] /cygdrive/f/Inetpub/cvsroot/da-aop/source/stack/jboss-aop
  |   | $ rm *.class; ant
  |   | Buildfile: build.xml
  |   | 
  |   | prepare:
  |   | 
  |   | compile:
  |   |     [javac] Compiling 6 source files to 
F:\Inetpub\cvsroot\da-aop\source\stack\jboss-aop
  |   |      [aopc] [deploying] 
file:/F:/Inetpub/cvsroot/da-aop/source/stack/jboss-aop/jboss-aop.xml
  |   |      [aopc] [deploy] <aspect> 
file:/F:/Inetpub/cvsroot/da-aop/source/stack/jboss-aop/jboss-aop.xml
  |   |      [aopc] [deploy] <aspect> 
file:/F:/Inetpub/cvsroot/da-aop/source/stack/jboss-aop/jboss-aop.xml
  |   |      [aopc] [deploy] <introduction> 
file:/F:/Inetpub/cvsroot/da-aop/source/stack/jboss-aop/jboss-aop.xml
  |   |      [aopc] [deploy] <pointcut> 
file:/F:/Inetpub/cvsroot/da-aop/source/stack/jboss-aop/jboss-aop.xml
  |   |      [aopc] [deploy] <pointcut> 
file:/F:/Inetpub/cvsroot/da-aop/source/stack/jboss-aop/jboss-aop.xml
  |   |      [aopc] [deploy] <pointcut> 
file:/F:/Inetpub/cvsroot/da-aop/source/stack/jboss-aop/jboss-aop.xml
  |   |      [aopc] [deploy] <bind> 
file:/F:/Inetpub/cvsroot/da-aop/source/stack/jboss-aop/jboss-aop.xml
  |   |      [aopc] [deploy] <bind> 
file:/F:/Inetpub/cvsroot/da-aop/source/stack/jboss-aop/jboss-aop.xml
  |   |      [aopc] [deploy] <bind> 
file:/F:/Inetpub/cvsroot/da-aop/source/stack/jboss-aop/jboss-aop.xml
  |   |      [aopc] [deploy] <bind> 
file:/F:/Inetpub/cvsroot/da-aop/source/stack/jboss-aop/jboss-aop.xml
  |   |      [aopc] [trying to transform] Driver
  |   |      [aopc] [no comp needed] 
F:\Inetpub\cvsroot\da-aop\source\stack\jboss-aop\Driver.class
  |   |      [aopc] [cannot compile] isInterface: IStackHeight
  |   |      [aopc] [no comp needed] 
F:\Inetpub\cvsroot\da-aop\source\stack\jboss-aop\IStackHeight.class
  |   |      [aopc] [trying to transform] Stack$StackObject
  |   |      [aopc] [no comp needed] 
F:\Inetpub\cvsroot\da-aop\source\stack\jboss-aop\Stack$StackObject.class
  |   |      [aopc] [trying to transform] Stack
  |   |      [aopc] [compiled] 
F:\Inetpub\cvsroot\da-aop\source\stack\jboss-aop\Stack.class
  |   |      [aopc] [trying to transform] StackHeight
  |   |      [aopc] [no comp needed] 
F:\Inetpub\cvsroot\da-aop\source\stack\jboss-aop\StackHeight.class
  |   |      [aopc] [trying to transform] StackHeightAspect
  |   |      [aopc] [no comp needed] 
F:\Inetpub\cvsroot\da-aop\source\stack\jboss-aop\StackHeightAspect.class
  |   |      [aopc] [trying to transform] StackSynchronizationAspect
  |   |      [aopc] [no comp needed] 
F:\Inetpub\cvsroot\da-aop\source\stack\jboss-aop\StackSynchronizationAspect.class
  |   | 
  |   | 
  |   | 
  |   | run:
  |   |      [java] Introduction failed: java.lang.ClassCastException
  |   |      [java] Introduction failed: java.lang.ClassCastException
  |   |      [java] Introduction failed: java.lang.ClassCastException
  |   | 
  |   | 
  |   | 
  |   | BUILD SUCCESSFUL
  |   | Total time: 3 seconds
  | 
  | So the whole work was for nothing? - There must be a simple explanation for this, 
what went wrong?
  | 
  | Trying to disassemble Stack:
  | 
  | [EMAIL PROTECTED] /cygdrive/f/Inetpub/cvsroot/da-aop/source/stack/jboss-aop
  |   | $ javap -c Stack
  |   | Compiled from "Stack.java"
  |   | public class Stack extends java.lang.Object implements 
org.jboss.aop.Advised,IStackHeight{
  |   | protected transient org.jboss.aop.ClassInstanceAdvisor _instanceAdvisor;
  |   | 
  |   | public Stack();
  |   |   Code: [...]
  | 
  | Why does the class cast fail? The whole package can be loaded at 
http://home.in.tum.de/prilmeie/jboss-aop-stack.tar.gz], please make sure that 
jboss-common.jar, jboss-aop.jar, javassist.jar, concurrent.jar, trove.jar and qdox.jar 
are in the same directory as the extracted files are. Otherwise it will not work
  | 
  | Apart from that I am very dissatisfied with the results. I had to use a cheap 
trick to get the results I wanted. Worse, the StackHeightAspect is now a necessary 
part of the Stack class, otherwise I never can use the size method. I even have to use 
the silly class cast whenever I want to use that specific method. A maintenance 
nightmare! - There must be a better way to achieve these results (This was my first 
attempt to use JBoss AOP, used version is beta3)
  | 
  | Are there any other mistakes I have made?

View the original post : 
http://www.jboss.org/index.html?module=bb&op=viewtopic&p=3840957#3840957

Reply to the post : 
http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=3840957


-------------------------------------------------------
This SF.Net email sponsored by Black Hat Briefings & Training.
Attend Black Hat Briefings & Training, Las Vegas July 24-29 - 
digital self defense, top technical experts, no vendor pitches, 
unmatched networking opportunities. Visit www.blackhat.com
_______________________________________________
JBoss-Development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to