5 Replies Latest reply on Oct 3, 2007 4:09 AM by Paul Marando

    a4j:push

    Patrick Madden Newbie

      I'm trying to get a4j:push working on one of my pages. I have an entity bean with application scope that listens to events regarding resources going up and down on an enterprise network. My page shows tables inside tabs of said resources. Resources can be things like services etc that are installed on arbitrary machines on my network. When a service goes up or down my enterprise bean recieves an event. When this occurs, I add an event to my PushEventListeners for a particular resource. The backend is all working and I can see that the events are being added correctly to each of my PushEventListeners.

      Here is a snip of the backend bean:

       /**
       * This method is used to push asynchronous events to the client
       * when we get add/remove or update events for grid members
       * we are interested in.
       */
       public void processEvent(GridMemberEvent event)
       {
       IGridMember member = event.getGridMember();
      
       if (member == null)
       {
       log.warn("Received a null IGridMember");
       return;
       }
      
       switch (event.getEventType())
       {
       case Added:
       case Removed:
       case Update:
       {
       log.info("Grid Member " + event.getEventType().toString() + " from address " + event.getSrcAddress() + ", " + member.toString());
      
       if (member instanceof IIndexingGridMember)
       {
       if (this.indexingMemberPushListener != null)
       {
       synchronized (this.indexingMemberPushListener)
       {
       log.info("Pushing event onto indexingMemberPushListener");
       this.indexingMemberPushListener.onEvent(new EventObject(this));
       }
       }
       else
       {
       log.warn("Recieved an IIndexingGridMember but our listener is null");
       }
       }
       else
       if (member instanceof ICloosterAppServer)
       {
       if (this.appServerMemberPushListener != null)
       {
       synchronized (this.appServerMemberPushListener)
       {
       log.info("Pushing event onto appServerMemberPushListener");
       this.appServerMemberPushListener.onEvent(new EventObject(this));
       }
       }
       else
       {
       log.warn("Recieved an ICloosterAppServer but our listener is null");
       }
       }
       }
       break;
      ....
      }
      


      I see the correct log messages on the backend but the page is not rerendering correctly.

      <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <ui:composition xmlns="http://www.w3.org/1999/xhtml"
       xmlns:s="http://jboss.com/products/seam/taglib"
       xmlns:ui="http://java.sun.com/jsf/facelets"
       xmlns:f="http://java.sun.com/jsf/core"
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:rich="http://richfaces.org/rich"
       xmlns:a4j="http://richfaces.org/a4j"
       template="layout/template.xhtml">
      
      <ui:define name="body">
      
       <h:messages globalOnly="true" styleClass="message"/>
      
       <a4j:region>
       <h:form>
       <a4j:push
       reRender="indexingGridMembersTable"
       eventProducer="#{enterpriseGrid.addIndexingGridMemberPushEventListener}"
       interval="10000"/>
       <a4j:push
       reRender="appServerGridMembersTable"
       eventProducer="#{enterpriseGrid.addAppServerGridMemberPushEventListener}"
       interval="10000"/>
       </h:form>
       </a4j:region>
       <h:form id="enterpriseGridViewForm">
       <f:facet name="header">Enterprise Grid Components</f:facet>
       <rich:tabPanel id="enterpriseGridViewTab" switchType="ajax">
      
       <rich:tab id="appServerGridMembersTab" label="Search Portals">
       <rich:dataTable id="appServerGridMembersTable" rows="10" value="#{enterpriseGrid.cloosterAppServers}" var="appServer">
       ...
       </rich:dataTable>
       </rich:tab>
      
       <rich:tab id="indexingGridMembersTab" label="Indexing Servers">
       <rich:dataTable id="indexingGridMembersTable" rows="10" value="#{enterpriseGrid.indexingGridMembers}" var="indexingServer">
       ... </rich:dataTable>
       </rich:tab>
       </rich:tabPanel>
       </h:form>
      
      </ui:define>
      
      </ui:composition>
      


      I've tried this with and without the a4j:region code.

      Any idea as to what I'm doing wrong?

      Thanks in advance and great job and 3.1.x.

      PVM

        • 1. Re: a4j:push
          Mikael Andersson Master

          Perhaps it is because they are in different forms?
          You can try and specify the full id for the table in reRender of the push element ( ex enterpriseGridViewForm:[???]:indexingGridMembersTab ).
          Or keep it all in the same form if possible.

          Just of the top of my head.

          Cheers,
          Mike

          • 2. Re: a4j:push
            Patrick Madden Newbie

            Thanks Mike,

            I really appreciate your reply. Unfortunately it didn't help.

            If anyone has a working example using a4j:push I'd really appreciate it.

            I do have it working using a4j:poll now (every 60 seconds) but I really don't like that. I'd much prefer to only render when it actually needs rendering as my infrastructure reacts to resources going up and down on network.

            Using poll I do get a strange exception once in a while. If anyone has seen this or has a suggestion I'd appreciate it.

            Caused by: javax.ejb.ConcurrentAccessException: no concurrent calls on stateful bean 'jboss.j2ee:service=EJB3,name=EnterpriseGridBean' (EJB3 4.3.13)
             at org.jboss.ejb3.stateful.StatefulInstanceInterceptor.invoke(StatefulInstanceInterceptor.java:73)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
             at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:106)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:46)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.stateful.StatefulContainer.localInvoke(StatefulContainer.java:204)
             at org.jboss.ejb3.stateful.StatefulLocalProxy.invoke(StatefulLocalProxy.java:100)
             at $Proxy114.getCloosterAppServers(Unknown Source)
             at sun.reflect.GeneratedMethodAccessor250.invoke(Unknown Source)
             at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
             at java.lang.reflect.Method.invoke(Method.java:597)
             at org.jboss.seam.util.Reflections.invoke(Reflections.java:21)
             at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:31)
             at org.jboss.seam.intercept.ClientSide
            21:19:50,127 ERROR [STDERR] Interceptor$1.proceed(ClientSideInterceptor.java:76)
             at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56)
             at org.jboss.seam.ejb.RemoveInterceptor.aroundInvoke(RemoveInterceptor.java:41)
             at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
             at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:106)
             at org.jboss.seam.intercept.ClientSideInterceptor.invoke(ClientSideInterceptor.java:54)
             at org.javassist.tmp.java.lang.Object_$$_javassist_5.getCloosterAppServers(Object_$$_javassist_5.java)
             at sun.reflect.GeneratedMethodAccessor249.invoke(Unknown Source)
             at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
             at java.lang.reflect.Method.invoke(Method.java:597)
             at javax.el.BeanELResolver.getValue(BeanELResolver.java:62)
             at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:53)
             at com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:64)
             at org.jboss.el.parser.AstPropertySuffix.getValue(AstPropertySuffix.java:53)
             at org.jboss.el.parser.AstValue.getValue(AstValue.java:67)
             at org.jboss.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
             at com.sun.facelets.el.TagValueExpression.getValue(TagValueExpression.java:71)
             ... 69 more
            


            • 3. Re: a4j:push
              Paul Marando Newbie

              G'day

              I am having the same problem, my code is quite simple, ripped almost
              straight from the demo. I have tried different combinations of single and multiforms, and outputpanels etc, and relative and absolute naming in the
              rerender field but no luck.

              here is my backing bean:

               private PushEventListener _listener;
               private String _thing = "nothing to see here";
              
               /**
               * Add a listener
               * @param listener passed from the view.
               */
               public void addListener(EventListener listener)
               {
               synchronized (listener)
               {
               if (_listener != listener)
               {
               _listener = (PushEventListener) listener;
               }
               }
               }
              
               /**
               * Trigger the event.
               */
               public void trigger()
               {
               System.out.println("event occurs");
               _thing = "triggered";
              
               synchronized (_listener)
               {
               _listener.onEvent(new EventObject(this));
               }
               }
              
              


              and the simple page:

              <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
              <ui:composition xmlns="http://www.w3.org/1999/xhtml"
               xmlns:ui="http://java.sun.com/jsf/facelets"
               xmlns:h="http://java.sun.com/jsf/html"
               template="layout/template.xhtml"
               xmlns:a4j="http://richfaces.org/a4j">
              
              <ui:define name="body">
              
               <h:form>
               <a4j:region>
               <a4j:push reRender="message" eventProducer="#{helpDesk.addListener}" interval="1000"/>
               </a4j:region>
               <h:outputText id="message" value="#{helpDesk.thing}"/>
               <a4j:log popup="false" level="ALL" style="width: 800px; height: 300px;"></a4j:log>
               </h:form>
              </ui:define>
              </ui:composition>
              


              the println works, and _thing gets set (just a little test string) but it doesn't seem to re-render. Nothing appears in the log either.

              I would also like to see a working example to find the bit I am missing.

              Cheers

              Paulie

              • 4. Re: a4j:push
                Dmitry Demyankov Novice

                 

                "paulie!" wrote:

                ..the println works, and _thing gets set (just a little test string) but it doesn't seem to re-render. Nothing appears in the log either..


                Have you tried to put
                <h:outputText id="message" value="#{helpDesk.thing}"/>
                inside a panel and reRender a panel instead of h:outputText?

                • 5. Re: a4j:push
                  Paul Marando Newbie

                  Thanks for the response,

                  Yes I had the outputText in an outputPanel that was the rerender target originally, I changed it to the above to match the poll example when I was getting a bit desperate.

                  Paulie!