4 Replies Latest reply on Jul 26, 2013 3:34 AM by rpelisse

    Implementing a Cache Provider for Seam 2

    rpelisse

      Hi all,

       

      I may have a missed a documentation page somewhere, but I did not find a tutorial or a "how to" describing the steps to implements one own cahce provider. Nevertheless, as it looked pretty straightforward in the code, I endeavoured to try to do so anyway, but - as one might have expected, I've ran into trouble.

       

      First thing first, why do I need a custom cache provider ? Because I want to expose a cache defined within JBoss AS cache container to the applicaton. This way, the application does not need to configure the cache (but its name) and all the cache configuration (distribution, ...) lies within the appserver. Also, this prevent embedding infinispan within the app, as the application will simply relies on the IFSP deployed within JBoss.

       

      I've therefore created a simple maven project to compile and package my cache provider : https://github.com/rpelisse/jboss-as-cache-provider

       

      This project holds 2 noteworthy files :

       

      $ tree src/main/*/

      src/main/java/

      `-- org

          `-- jboss

              `-- seam

                  `-- cache

                      `-- JBossASCacheProvider.java      ----------> My CacheProvider implementation

      src/main/resources/

      `-- org

          `-- jboss

              `-- seam

                  `-- cache-2.3.xsd                               -----------> A copy of the XSD coming from JBoss Seam JAR, augmented with my cache definition

       

      The implementation have the following annotations (more/less copied over from the infinispan-cache-provider):

       

      @Name("org.jboss.seam.cache.cacheProvider")

      @Scope(APPLICATION)

      @BypassInterceptors

      @Install(value = false, precedence = BUILT_IN, classDependencies = { "org.infinispan.tree.TreeCache", "org.jgroups.MembershipListener" })

      @AutoCreate

      public class JBossASCacheProvider<T> extends CacheProvider<T> {

       

      The XSD had been modified to contains my cache definition:

       

      ...

         <xs:element name="jboss-as-cache-provider">

            <xs:annotation>

               <xs:documentation>Uses InfiniSpan embedded in JBoss EAP as a Cache provider</xs:documentation>

            </xs:annotation>

            <xs:complexType mixed="true">

               <xs:attributeGroup ref="components:attlist.component" />

               <xs:attributeGroup ref="cache:attlist.cacheProvider" />

            </xs:complexType>

        </xs:element>

      ...

       

      I've modified the blog example app to embedded my jar at the root of the EAR and set it to be loaded before the jboss-seam.jar:

       

      diff --git a/demo/jboss-seam/examples/blog/blog-ear/pom.xml b/demo/jboss-seam/examples/blog/blog-ear/pom.xml

      index 9e64732..ef92845 100644

      --- a/demo/jboss-seam/examples/blog/blog-ear/pom.xml

      +++ b/demo/jboss-seam/examples/blog/blog-ear/pom.xml

      @@ -30,7 +30,14 @@

                <artifactId>jboss-seam</artifactId>

                <type>ejb</type>

                <scope>compile</scope>

      -      </dependency>

      +     </dependency>

      +     <dependency>

      +        <groupId>org.jboss.seam</groupId>

      +        <artifactId>jboss-as-cache-provider</artifactId>

      +        <version>1.0-SNAPSHOT</version>

      +        <type>ejb</type>

      +        <scope>compile</scope>

      +     </dependency>

          </dependencies>

       

          <build>

      @@ -62,9 +69,16 @@

       

                         <ejbModule>

                            <groupId>org.jboss.seam</groupId>

      +                     <artifactId>jboss-as-cache-provider</artifactId>

      +                     <bundleFileName>jboss-as-cache-provider-1.0-SNAPSHOT.jar</bundleFileName>

      +                  </ejbModule>

      +

      +                  <ejbModule>

      +                     <groupId>org.jboss.seam</groupId>

                            <artifactId>jboss-seam</artifactId>

                            <bundleFileName>jboss-seam.jar</bundleFileName>

                         </ejbModule>

       

      (Also, initialize in order is set to true: <initializeInOrder>true</initializeInOrder>)

       

      At last, i've modified the component.xml to use my cache provider:

       

      diff --git a/demo/jboss-seam/examples/blog/blog-web/src/main/webapp/WEB-INF/components.xml b/demo/jboss-seam/examples/blog/blog-web/src/main/webapp/WE

      index 862703c..b341301 100644

      --- a/demo/jboss-seam/examples/blog/blog-web/src/main/webapp/WEB-INF/components.xml

      +++ b/demo/jboss-seam/examples/blog/blog-web/src/main/webapp/WEB-INF/components.xml

      @@ -30,7 +30,7 @@

             </theme:available-themes>

          </theme:theme-selector>

       

      -   <cache:infinispan-cache-provider/>

      +   <cache:jboss-as-cache-provider/>

       

      When I deploy the application, no complains (even if I do NOT shipped my modified XSD, so it seems like no validation on the name/type of the cache provider is done by Seam), but when I load the page, I run into a NPE:

       

      08:07:54,530 SEVERE [javax.enterprise.resource.webcontainer.jsf.application] (http-/127.0.0.1:8080-4) Error Rendering View[/index.xhtml]: java.lang.NullPointerException

              at org.jboss.seam.ui.renderkit.CacheRendererBase.doEncodeChildren(CacheRendererBase.java:40) [jboss-seam-ui-2.3.1.Final-redhat-1.jar:2.3.1.Final-redhat-1]

              at org.jboss.seam.ui.util.cdk.RendererBase.encodeChildren(RendererBase.java:92) [jboss-seam-ui-2.3.1.Final-redhat-1.jar:2.3.1.Final-redhat-1]

              at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:851) [jboss-jsf-api_2.1_spec-2.1.19.1.Final-redhat-1.jar:2.1.19.1.Final-redhat-1]

              at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1779) [jboss-jsf-api_2.1_spec-2.1.19.1.Final-redhat-1.jar:2.1.19.1.Final-redhat-1]

              at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1782) [jboss-jsf-api_2.1_spec-2.1.19.1.Final-redhat-1.jar:2.1.19.1.Final-redhat-1]

              at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1782) [jboss-jsf-api_2.1_spec-2.1.19.1.Final-redhat-1.jar:2.1.19.1.Final-redhat-1]

              at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:439) [jsf-impl-2.1.19-redhat-1.jar:2.1.19-redhat-1]

              at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:124) [jsf-impl-2.1.19-redhat-1.jar:2.1.19-redhat-1]

              at org.jboss.seam.jsf.SeamViewHandler.renderView(SeamViewHandler.java:184) [jboss-seam.jar:2.3.1.Final-redhat-1]

              at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:286) [jboss-jsf-api_2.1_spec-2.1.19.1.Final-redhat-1.jar:2.1.19.1.Final-redhat-1]

              at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120) [jsf-impl-2.1.19-redhat-1.jar:2.1.19-redhat-1]

              at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) [jsf-impl-2.1.19-redhat-1.jar:2.1.19-redhat-1]

              at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139) [jsf-impl-2.1.19-redhat-1.jar:2.1.19-redhat-1]

              at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594) [jboss-jsf-api_2.1_spec-2.1.19.1.Final-redhat-1.jar:2.1.19.1.Final-redhat-1]

              at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:295) [jbossweb-7.2.0.Final-redhat-1.jar:7.2.0.Final-redhat-1]

              at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [jbossweb-7.2.0.Final-redhat-1.jar:7.2.0.Final-redhat-1]

              at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:832) [jbossweb-7.2.0.Final-redhat-1.jar:7.2.0.Final-redhat-1]

       

       

       

       

       

       

       

      Did I miss some steps here ? Is there some documented procedure I should follow ? Is it even possible to plug a cache provider 'outside' the jboss-seam jar ?

       

      Thanks for your feedback !