5 Replies Latest reply on Mar 13, 2009 6:15 AM by pmuir

    Make a default interceptor the inner interceptor

    pmuir

      Given

      <ejb-jar xmlns="http://java.sun.com/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"
       version="3.0">
      
       <interceptors>
       <interceptor>
       <interceptor-class>org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
       </interceptor>
       </interceptors>
      
       <assembly-descriptor>
       <interceptor-binding>
       <ejb-name>*</ejb-name>
       <interceptor-class>org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
       </interceptor-binding>
       </assembly-descriptor>
      
      </ejb-jar>


      how can I make sure that SeamInterceptor is always the inner most interceptor in the stack? I see that the EJB3 spec allows me specify a total order (if I know the interceptors to order), but I can't see how to ask for an interceptor to be inside unknown interceptors.

      So, is there a spec'd way to do this? Or a JBoss way?

        • 1. Re: Make a default interceptor the inner interceptor
          wolfc

           

          "pete.muir@jboss.org" wrote:
          ...
          So, is there a spec'd way to do this? Or a JBoss way?

          No and no.

          We could create a new interceptor group which allows for ordering on a new level. But that should not be be limited to Seam so we would need ordering within that new group as well.

          What's the problem you're trying to resolve? If it's 'configuration errors', then adding complexity to relieve that is not an option.

          • 2. Re: Make a default interceptor the inner interceptor
            pmuir

             

            "wolfc" wrote:
            What's the problem you're trying to resolve? If it's 'configuration errors', then adding complexity to relieve that is not an option.


            That we perform JSR-299 injection and interceptor binding into an EJB using a default interceptor. This should be called before any user interceptors.

            • 3. Re: Make a default interceptor the inner interceptor
              pmuir

              Ok, by default "default interceptors" are invoked in the order they are defined in ejb-jar.xml, and before any class level interceptors. I guess we just go with inserting our interceptor at the top of chain for now. We can also check the order the user defines, and WARN if ours isn't first I think...

              • 4. Re: Make a default interceptor the inner interceptor
                jaikiran

                 

                "pete.muir@jboss.org" wrote:

                That we perform JSR-299 injection and interceptor binding into an EJB using a default interceptor. This should be called before any user interceptors.


                So i guess, the Seam interceptor should be called irrespective of whether the user has defined any interceptors for the application. In that case, shouldn't the seam interceptor be defined/configured some place else (at server level) instead of the ejb-jar.xml which is per application?


                • 5. Re: Make a default interceptor the inner interceptor
                  pmuir

                  Sorry guys, I was being super confusing here ;-)

                  First of all, I'm working on the Web Beans interceptor not Seam.

                  Second, I was just representing the way we add the interceptor as XML, actually we add it programatically in a deployer by manipulating the metadata:

                  public class WBEjbInterceptorMetadataDeployer extends WebBeansAwareMetadataDeployer<JBossMetaData>
                  {
                   private static final String INTERCEPTOR_CLASS_NAME = "org.jboss.webbeans.ejb.SessionBeanInterceptor";
                  
                   private InterceptorMetaData SBI;
                   private InterceptorBindingMetaData IBMD;
                  
                   public WBEjbInterceptorMetadataDeployer()
                   {
                   super(JBossMetaData.class);
                  
                   addInput(DeployersUtils.WEB_BEANS_FILES);
                   addInput("merged." + JBossMetaData.class.getName());
                   setStage(DeploymentStages.POST_CLASSLOADER);
                  
                   // create interceptor metadata instance
                   SBI = new InterceptorMetaData();
                   SBI.setInterceptorClass(INTERCEPTOR_CLASS_NAME);
                  
                   // create interceptor binding metadata instance
                   IBMD = new InterceptorBindingMetaData();
                   InterceptorClassesMetaData interceptorClasses = new InterceptorClassesMetaData();
                   interceptorClasses.add(INTERCEPTOR_CLASS_NAME);
                   IBMD.setInterceptorClasses(interceptorClasses);
                   IBMD.setEjbName("*");
                   }
                  
                   protected void internalDeploy(VFSDeploymentUnit unit, JBossMetaData jbmd, VirtualFile wbXml) throws DeploymentException
                   {
                   InterceptorsMetaData interceptors = jbmd.getInterceptors();
                   if (interceptors == null)
                   {
                   InterceptorsMetaData imd = new InterceptorsMetaData();
                   imd.add(SBI);
                   EjbJar3xMetaData ejmd = new EjbJar30MetaData();
                   ejmd.setInterceptors(imd);
                  
                   jbmd.merge(null, ejmd);
                   }
                   else
                   {
                   interceptors.add(SBI); // clone?
                   }
                  
                   JBossAssemblyDescriptorMetaData assemblyDescriptor = jbmd.getAssemblyDescriptor();
                   if (assemblyDescriptor == null)
                   {
                   assemblyDescriptor = new JBossAssemblyDescriptorMetaData();
                   jbmd.setAssemblyDescriptor(assemblyDescriptor);
                   }
                   InterceptorBindingsMetaData interceptorBindings = assemblyDescriptor.getInterceptorBindings();
                   if (interceptorBindings == null)
                   {
                   interceptorBindings = new InterceptorBindingsMetaData();
                   assemblyDescriptor.setInterceptorBindings(interceptorBindings);
                   }
                   // Add this as the first binding in the list so that it is called first...
                   interceptorBindings.add(0, IBMD); // clone?
                  
                   // Check to see there is a defined order; if we aren't first, warn
                   for (InterceptorBindingMetaData interceptorBinding : interceptorBindings)
                   {
                   if (interceptorBinding.getInterceptorOrder() != null && ! interceptorBinding.getInterceptorOrder().isEmpty())
                   {
                   if (!INTERCEPTOR_CLASS_NAME.equals(interceptorBinding.getInterceptorOrder().iterator().next()))
                   {
                   log.warn("The Web Beans SessionnBeanInterceptor is not the inner most EJB interceptor in this deployment. JSR299 injection may not work correctly. Specify " + INTERCEPTOR_CLASS_NAME + " as the first interceptor in the interceptor ordering for " + interceptorBinding.getEjbName());
                   }
                   // TODO automagically make ours the first?
                   }
                   }
                   }
                  }


                  This includes adding our interceptor as the 0th interceptor, and ommitting a warn if people order interceptors, and ours isn't first.
                  This includes the change I wrote about -