5 Replies Latest reply on Sep 25, 2008 1:44 PM by Olivier Thierry

    How to get component name in interceptor

    Olivier Thierry Apprentice

      Hi,


      I created an interceptor for Seam components. This interceptor needs to get the component name, but I can't find the way to get it from InvocationContext. I thought about looking for annotations of the class I get with InvocationContext.getTarget() method, but you can have many Seam components for one class. So is there a way to do this ?


      Thanks in advance ;)

        • 1. Re: How to get component name in interceptor
          Pawel Wrzeszcz Novice

          Hm... try making your interceptor a subclass of org.jboss.seam.intercept.AbstractInterceptor. It has getComponent() method :)


          -Pawel

          • 2. Re: How to get component name in interceptor
            Olivier Thierry Apprentice

            Thanks. I followed your suggestion and wrote this interceptor :



            public class ApplicativeTraceInterceptor extends AbstractInterceptor
            {
                @javax.interceptor.AroundInvoke
                public Object aroundInvoke(org.jboss.seam.intercept.InvocationContext ctx)
                    throws Exception 
                {
                     Log applicativeLogger = Logging.getLog(ctx.getTarget().getClass()); 
                        applicativeLogger.info(
                                  "Execute service '#0' for component '#1'", 
                                  ctx.getMethod().getName(), 
                                  getComponent().getName());
                    
                    try
                    {
                        return ctx.proceed();
                    }
                    catch (Exception e)
                    {
                        throw e;
                    }
                }
            }



            I use OpenEJB to run my tests (encountered serious problems with JBoss embedded), but on startup I have a OutOfMemoryError. See the startup logs below.


            Running TestSuite
            [Parser] Running:
              C:\Documents\t4\core\t4-core-utils\core\src\test\resources\testng.xml
            
            Apache OpenEJB 3.0    build: 20080408-04:13
            http://openejb.apache.org/
            INFO - openejb.home = C:\Documents\t4\core\t4-core-utils\core
            INFO - openejb.base = C:\Documents\t4\core\t4-core-utils\core\src\test\resources
            INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service)
            INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager)
            INFO - Configuring Service(id=t4Seam, type=Resource, provider-id=Default JDBC Database)
            INFO - Configuring Service(id=Default JDK 1.3 ProxyFactory, type=ProxyFactory, provider-id=Default JDK 1.3 ProxyFactory)
            INFO - Configuring Service(id=My CMP Container, type=Container, provider-id=Default CMP Container)
            INFO - Configuring Service(id=My BMP Container, type=Container, provider-id=Default BMP Container)
            INFO - Configuring Service(id=My Stateful Container, type=Container, provider-id=Default Stateful Container)
            INFO - Configuring Service(id=My Stateless Container, type=Container, provider-id=Default Stateless Container)
            INFO - Found EjbModule in classpath: C:\Documents\t4\core\t4-core-utils\core\target\classes
            INFO - Configuring app: C:\Documents\t4\core\t4-core-utils\core\target\classes
            java.lang.OutOfMemoryError: Java heap space
            INFO - Configuring PersistenceUnit(name=t4Seam, provider=org.hibernate.ejb.HibernatePersistence)
            INFO - Auto-creating a Resource with id 't4SeamNonJta' of type 'DataSource for 't4Seam'.
            INFO - Configuring Service(id=t4SeamNonJta, type=Resource, provider-id=t4Seam)
            INFO - Adjusting t4Seam <jta-data-source> to 't4Seam'
            INFO - Adjusting t4Seam <non-jta-data-source> to 't4SeamNonJta'
            ERROR - ERROR ... null:     Cannot validate jar: Java heap space
            ERROR - Invalid AppModule(path=C:\Documents\t4\core\t4-core-utils\core\target\classes)
            WARN - Jar not loaded. C:\Documents\t4\core\t4-core-utils\core\target\classes.  Module failed validation. AppModule(path=C:\Documents\t4\core\t4-core-utils\core\target\classes)
            



            I use Seam 2.1.0.BETA1. Do you have any idea what happens ? Is there something wrong in the way I wrote my interceptor ?

            • 3. Re: How to get component name in interceptor
              Olivier Thierry Apprentice

              I just found the solution. But there are things I can't understand ...


              I created a ApplicativeTrace annotation this way :



              @Target(ElementType.TYPE)
              @Retention(RetentionPolicy.RUNTIME)
              @Interceptors(ApplicativeTraceInterceptor.class)
              public @interface ApplicativeTrace {
              
              }



              Then I used @org.jboss.seam.annotations.intercept.AroundInvoke annotation instead of @javax.interceptor.AroundInvoke one in my interceptor.



              public class ApplicativeTraceInterceptor extends AbstractInterceptor
              {
                  @org.jboss.seam.annotations.intercept.AroundInvoke
                  public Object aroundInvoke(org.jboss.seam.intercept.InvocationContext ctx)
                      throws Exception 
                  {
                       Log applicativeLogger = Logging.getLog(ctx.getTarget().getClass()); 
                          applicativeLogger.info(
                                    "Execute service '#0' for component '#1'", 
                                    ctx.getMethod().getName(), 
                                    getComponent().getName());
                      
                      try
                      {
                          return ctx.proceed();
                      }
                      catch (Exception e)
                      {
                          throw e;
                      }
                  }
              }



              Finally I use my ApplicativeTrace annotation in Seam components I need to intercept :



              @ApplicativeTrace
              public class ProcessInternalServiceBean 
                  extends ProcessInternalServiceBase 
                  implements ProcessInternalServiceLocal
              {
                  ...
              }



              But I can't understand why interceptor is not active when I add @javax.interceptor.Interceptors(ApplicativeTraceInterceptor.class) to the Seam components I want to intercept.


              Is there something I misunderstood ?

              • 4. Re: How to get component name in interceptor
                Pawel Wrzeszcz Novice

                But I can't understand why interceptor is not active when I add @javax.interceptor.Interceptors(ApplicativeTraceInterceptor.class) to the Seam components I want to intercept.

                Is there something I misunderstood ?


                There are 2 different types of interceptors: Seam and EJB3 interceptors.


                To create a Seam interceptor you use @org.jboss.seam.annotations.intercept.AroundInvoke, create an annotation and then annotate Seam components that should be intercepted (like you did above).


                To create an EJB3 interceptor you use @javax.interceptor.Interceptors (I'm not sure if subclassing Seam AbstractInterceptor works then) and use @Interceptors to apply it (more).


                Cheers,
                -Pawel

                • 5. Re: How to get component name in interceptor
                  Olivier Thierry Apprentice

                  OK, I understand better now.
                  I confirm that subclassing Seam AbstractInterceptor to create a EJB3 interceptor doesn't work, the interceptor is never called.
                  Thanks a lot Pawel ;)