7 Replies Latest reply on Oct 6, 2005 2:18 PM by Adrian Brock

    has pointcut and interfaces

    Adrian Brock Master

      I've added a test that shows a problem with the way the pointcut matcher
      handles interfaces and "has" pointcut. Or more accurately the way reflection
      describes it.

      The pointcut expression is

      execution(* *->*(..)) AND has(* org.jboss.test.aop.basic.InterfaceUsedInHas->*(..))

      or intercept all methods if the POJO has a method from "InterfaceUsedInUs".
      TEST Interface used in has
      org.jboss.test.aop.basic.InterfaceUsedInHasImpl methods=[public void org.jboss.test.aop.basic.InterfaceUsedInHasImpl.someMethod(), public org.jboss.aop.InstanceAdvisor
       org.jboss.test.aop.basic.InterfaceUsedInHasImpl._getInstanceAdvisor(), public org.jboss.aop.Advisor org.jboss.test.aop.basic.InterfaceUsedInHasImpl._getAdvisor(), pub
      lic void org.jboss.test.aop.basic.InterfaceUsedInHasImpl._setInstanceAdvisor(org.jboss.aop.InstanceAdvisor), public void org.jboss.test.aop.basic.InterfaceUsedInHasImp
      l.org$jboss$test$aop$basic$InterfaceUsedInHasImpl$someMethod$aop()]
      org.jboss.test.aop.basic.SubclassInterfaceUsedInHasImpl methods=[public void org.jboss.test.aop.basic.SubclassInterfaceUsedInHasImpl.someOtherMethod(), public org.jbos
      s.aop.Advisor org.jboss.test.aop.basic.SubclassInterfaceUsedInHasImpl._getAdvisor(), public void org.jboss.test.aop.basic.SubclassInterfaceUsedInHasImpl.org$jboss$test
      $aop$basic$SubclassInterfaceUsedInHasImpl$someOtherMethod$aop()]
      
      Testcase: testInterfaceUsedInHas took 0.014 sec
       Caused an ERROR
      should have intercepted InterfaceUsedInHasImpl.someMethod()
      java.lang.RuntimeException: should have intercepted InterfaceUsedInHas.someMethod()
       at org.jboss.test.aop.basic.AOPTester.testInterfaceUsedInHas(AOPTester.java:555)
      


      The problem is that the implementation class only has such a method from the
      class it extends and then it is said to come from the implementation class.
      public class SubclassInterfaceUsedInHasImpl extends InterfaceUsedInHasImpl
      {
       public void someOtherMethod()
       {
       }
      }
      


      I bring this issue up because I'm looking at how to "introduce" an interface
      without seeding the target class (and it is also in the context that all methods should
      be intercepted so it is not really an introduction).
      i.e. JCA 1.5 message inflow
      execution(* *->*(..)) AND has(* javax.resource.spi.endpoint.MessageEndpoint->*(..))

      where the MessageEndpoint methods and "onMessage(...)" are all intercepted.

        • 1. Re: has pointcut and interfaces
          Bill Burke Master

          so you want to intercept all methods of a certain interface?

          Any suggestions on the syntax?

          execution(* $instanceof{foo.bar}->$implementing(..))
          




          • 2. Re: has pointcut and interfaces
            Adrian Brock Master

            Cool, that is what I want!

            execution(* $instanceof{org.jboss.test.aop.basic.InterfaceUsedInHas}->*(..))
            


            i.e. If I implement this interface, advise all methods.

            • 3. Re: has pointcut and interfaces
              Bill Burke Master

              but $instanceof already exists.

              What doesn't exist is, intercept only those methods that implement/override a certain interface/class.

              • 4. Re: has pointcut and interfaces
                Adrian Brock Master

                 

                "bill.burke@jboss.com" wrote:
                but $instanceof already exists.

                Yes and I didn't realise that was the solution.


                What doesn't exist is, intercept only those methods that implement/override a certain interface/class.


                Isn't that the definition of an introduction? I wanted all methods if it implements a certain interface and was trying to use "has()" which didn't work because of the way
                reflection described the method.

                • 5. Re: has pointcut and interfaces
                  Bill Burke Master

                  pointcut matching matches each thing separate

                  for:

                  execution(* $instanceof{foo.bar}->*(..))
                  


                  it matches the return type "*"

                  then it matches $instanceof{foo.bar} to the class you are instrumenting

                  then it matches the method name (which is *) then the params.

                  Same with has as well. 'has' was originally written for expressions like:

                  execution(*->new(..)) AND has(* *->@org.jboss.Inject(..))
                  


                  which states, intercept any constructor where the class has a method annotated with @Inject.

                  • 6. Re: has pointcut and interfaces
                    Adrian Brock Master

                    Are you saying this shouldn't be working?

                    
                     public void testInterfaceUsedInHas()
                     {
                    <snip/>
                    
                     CallerInterceptor.called = false;
                     System.out.println("About to invoke pojo.someMethod()");
                     pojo.someMethod();
                     if (CallerInterceptor.called == false) throw new RuntimeException("should have intercepted InterfaceUsedInHas.someMethod()");
                    
                     CallerInterceptor.called = false;
                     System.out.println("About to invoke pojo.someOtherMethod()");
                     pojo.someOtherMethod();
                     if (CallerInterceptor.called == false) throw new RuntimeException("should have intercepted SubclassInterfaceUsedInHasImpl.someOtherMethod()");
                     }
                    



                    About to invoke pojo.someMethod()
                    Called: [advisedMethod=public void org.jboss.test.aop.basic.InterfaceUsedInHasImpl.someMethod(), unadvisedMethod=public void org.jboss.test.aop.basic.InterfaceUsedInHa
                    sImpl.org$jboss$test$aop$basic$InterfaceUsedInHasImpl$someMethod$aop(), metadata=null, targetObject=org.jboss.test.aop.basic.SubclassInterfaceUsedInHasImpl@1e328e0, ar
                    guments=null]
                    About to invoke pojo.someOtherMethod()
                    Called: [advisedMethod=public void org.jboss.test.aop.basic.SubclassInterfaceUsedInHasImpl.someOtherMethod(), unadvisedMethod=public void org.jboss.test.aop.basic.Subc
                    lassInterfaceUsedInHasImpl.org$jboss$test$aop$basic$SubclassInterfaceUsedInHasImpl$someOtherMethod$aop(), metadata=null, targetObject=org.jboss.test.aop.basic.Subclass
                    InterfaceUsedInHasImpl@1e328e0, arguments=null]
                    


                    • 7. Re: has pointcut and interfaces
                      Adrian Brock Master

                      I think I see what you are saying.

                      The instanceof only works if the interface is on the class or super class
                      of the method being advised.
                      It doesn't match methods that are declared on the class above the one tagged with the interface.

                      Which returns me to my initial problem. How do I say advise all methods on an
                      object if the object implements an interface?