1 2 Previous Next 20 Replies Latest reply on Apr 9, 2008 5:23 PM by darthmaul

    Interception on JavaBeans Not Working

    darthmaul

      I am writing a Seam application using JavaBeans on WebLogic 9.2.  Obviously, I don't have access to EJB3, but I am trying to use Seam interceptors to help with exception handling.


      There are three classes in question.


      First, here is the interceptor:


      import javax.persistence.NoResultException;
      import javax.interceptor.AroundInvoke;
      import javax.interceptor.InvocationContext;
      
      public final class NoSuchWidgetExceptionInterceptor extends Object {
         @AroundInvoke
         public Object throwNoSuchWidgetException(InvocationContext invocation) throws Exception {
            try {
               return invocation.proceed();
            }
            catch (NoResultException nre) {
               throw new NoSuchWidgetException(nre);
            }
         }
      }
      



      Next, here is the interceptor turned into an annotation:



      import javax.interceptor.Interceptors;
      import java.lang.annotation.Target;
      import java.lang.annotation.Retention;
      import static java.lang.annotation.ElementType.METHOD;
      import static java.lang.annotation.RetentionPolicy.RUNTIME;
      
      @Target(METHOD)
      @Retention(RUNTIME)
      @Interceptors(NoSuchWidgetExceptionInterceptor.class)
      public @interface NoSuchWidget {
      }
      



      Finally, here is the annotation applied to my business object:



      @NoSuchWidget
      public Widget findWidgetByNumber(String number) {
            return(Widget) em.createNamedQuery("findWidgetByNumber").setParameter("number", number).getSingleResult();
      }
      



      Unfortunately, my tests show that the annotation is having no effect whatsoever.  I am not getting any errors, but instead it is as if the annotation hasn't been applied at all.


      Any insight as to why this is is appreciated.


      Thanks.


        • 1. Re: Interception on JavaBeans Not Working
          gjeudy

          If you don't have some framework code that does the weaving of the interceptor by discovering the annotations at runtime your annotation won't have any effect. How do you think Seam, EJB3 container or other annotation-using framework are working ? They discover the annotations at runtime and wrap your business object inside a dynamic proxy. The proxy has it's interceptor stack defined and calls the interceptors in order before calling your business method. It's all transparent to the client code because the proxy is implementing your business interface. I'm not saying all frameworks are doing exactly this but the concept of proxying your business object is quite common for that type of work.


          I never added a custom annotation myself but i'm pretty sure you need to find a way to weave your interceptor call to your business object. Declaring annotation doesn't do anything until you have code that processes it, usually using reflection/introspection at runtime.


          Regards,

          • 2. Re: Interception on JavaBeans Not Working
            darthmaul

            Guillaume, I appreciate your response.  I am confused about something you said though:



            If you don't have some framework code that does the weaving of the interceptor by discovering the annotations at runtime your annotation won't have any effect.


            OK, but isn't that precisely what Seam is?


            I pretty much followed the content found here:


            5.2. Seam interceptors


            And I would point out this comment in that chapter:



            You can even use Seam interceptors with JavaBean components, not just EJB3 beans!

            So it seems to me that Seam should in fact do all the proxy stuff if everything is written right.  As far as areas to explore with regard to this problem, for example, I use javax.interceptor.* when perhaps I should use org.jboss.seam.intercept.* to make things work.  Or maybe I need to give my interceptor a name with @Name.


            Any insight is appreciated.


            Thanks.

            • 3. Re: Interception on JavaBeans Not Working
              christian.bauer

              Your Widget needs to be a Seam component, so that is where the @Name goes. You also need to instantiate it (lookup, injection) through the Seam container, so the proxy can be wrapped with interceptors.


              • 4. Re: Interception on JavaBeans Not Working
                gjeudy

                Sorry I might have misread, didnt see you were attempting to implement a seam interceptor, I thought you were just trying something standalone.


                Anyways, I would add definitely use


                org.jboss.seam.annotations.intercept.*



                when you declare your interceptor. Seam interceptors are a separate beast than EJB3 interceptors so steer clear of


                javax.interceptor.*



                unless you want to use EJB3 interceptor in which case your widget needs to be an EJB and the weaving/proxying is performed by the EJB3 container instead of Seam when you first get a reference to your bean.





                • 5. Re: Interception on JavaBeans Not Working
                  darthmaul

                  I figured as much, so I made the change you suggested.  Still, no luck.


                  Thanks though.

                  • 6. Re: Interception on JavaBeans Not Working
                    christian.bauer

                    Guillaume Jeudy wrote on Apr 08, 2008 10:18 PM:


                    Seam interceptors are a separate beast than EJB3 interceptors so steer clear of

                    javax.interceptor.*



                    unless you want to use EJB3 interceptor in which case your widget needs to be an EJB and the weaving/proxying is performed by the EJB3 container instead of Seam when you first get a reference to your bean.



                    This is not correct.

                    • 7. Re: Interception on JavaBeans Not Working
                      darthmaul

                      Well, Christian, I have Widget annotated with @Name.  Also, the class I am attempting to apply the interceptor to is a utility class that also has @Name.  Here is that class:



                      @Name("queryService")
                      public class QueryService extends Object {
                         @In
                         EntityManager em;
                         @Logger
                         protected Log logger;
                      
                         @NoSuchWidget
                         public Widget findWidgetByNumber(String number) {
                            return(Widget) em.createNamedQuery("findWidgetByNumber").setParameter("number", number).getSingleResult();
                      }
                      



                      Are you suggesting I also need to inject @NoSuchWidget?  Or NoSuchWidgetExceptionInterceptor?


                      Thanks for any insight.

                      • 8. Re: Interception on JavaBeans Not Working
                        gjeudy

                        ok sorry if I can't help you more at this point. Is your interceptor package in the same jar as your seam component ? My last guess would be, make sure both are in jars with seam.properties file in the META-INF so Seam would pick them up at startup.

                        • 9. Re: Interception on JavaBeans Not Working
                          christian.bauer

                          Retrieval (instantiation) through the EntityManager is not instantiation or injection through the Seam container. In other words, it doesn't work if Widget is instantiated by the persistence provider (ie. it is an @Entity).


                          • 10. Re: Interception on JavaBeans Not Working
                            darthmaul

                            So do I go with javax.interceptor.* then?

                            • 11. Re: Interception on JavaBeans Not Working
                              darthmaul

                              OK, that's cool.  Widget is indeed an @Entity.  Still, the interceptor is being applied not to Widget but to QueryService, which just happens to be searching for a Widget.  I don't think Widget has anything to do with this problem.


                              Any more clarification is much appreciated.


                              Thanks.

                              • 12. Re: Interception on JavaBeans Not Working
                                christian.bauer

                                Quoting the docs:



                                Seam builds upon the interceptor framework in EJB3 by allowing you to use @Interceptors as a meta-annotation for class level interceptors (those annotated @Target(TYPE)).


                                Yours is not a class-level interceptor.

                                • 13. Re: Interception on JavaBeans Not Working
                                  gjeudy

                                  Christian can you please clarify how:


                                  javax.interceptor.* 



                                  is used in Seam? How my assertion is not correct? I was under the impression that javax.interceptor interfaces and annotations would have to be used within an EJB3 container. Am I wrong ?


                                  I would be pleased to learn the answer.

                                  • 14. Re: Interception on JavaBeans Not Working
                                    darthmaul

                                    Ahhhh...good point.  I changed things to @Target(TYPE), but alas no change.


                                    Then again, this really is the sort of annotation that should be at the method level.  So if such a thing is impossible in the Seam-JavaBean world, then perhaps I should scrap the idea altogether.


                                    I shall keep tinkering...


                                    Thanks.

                                    1 2 Previous Next