9 Replies Latest reply: May 11, 2012 10:41 AM by Jérémy Caramelle RSS

    Push with own JMS  queue

    Jérémy Caramelle Newbie

      Hello,

       

      I'm trying to use a4j:push richfaces tag.

       

      I have my own JMS queue defined in the application_context file :

       

      <bean id="jmsConnectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">

                          <property name="transportType" value="1" />

                          <property name="queueManager" value="QUEUEMANAGER" />

                          <property name="hostName" value="hostName" />

                          <property name="port" value="26007" />

                          <property name="channel" value="SYSTEM.CH.CHANNEL" />

      </bean>

       

      I obviously know the name of the JMS queue.

       

      So, i've several question about push tag :

            - Do I have to put the context param :

         

      <context-param>

                               <param-name>org.richfaces.push.jms.enabled</param-name>

                               <param-value>true</param-value>

      </context-param>

       

           - Which adress have I to put in the "adress" parameter of the a4j:push tag ?

       

           - Do I need anything else ?

       

      Thanks for your answers.

      Jérémy Caramelle

        • 1. Re: Push with own JMS  queue
          Jérémy Caramelle Newbie

          Hello again,

           

          Maybe my question wasn't clear.

           

          I would like to plug my <a4j:push> to an existing JMS queue.

           

          Is this possible ?

           

          Thanks.

          • 2. Re: Push with own JMS  queue
            Lukáš Fryč Master

            Hi Jeremy,

             

            you can subscribe only to topics.

             

            There is fundamental difference:

            • queue delivers to one subscriber
            • topic delivers to all subscribers

             

            From architectural point, we decided not to support queues,

            since the scenario of delivering to one particular browser is unique.

            • 3. Re: Push with own JMS  queue
              Jérémy Caramelle Newbie

              Ok, we have created a Topic like this :

               

              define topic(MyTopic) topicstr(/MyTopicName)

               

              I've registered the Topic in Spring configuration file :

               

              <bean id="jmsConnectionFactory" class="com.ibm.mq.jms.MQTopicConnectionFactory">

                                  <property name="transportType" value="1" />

                                  <property name="queueManager" value="QueueManager" />

                                  <property name="hostName" value="host" />

                                  <property name="port" value="10010" />

                                  <property name="channel" value="SYSTEM.DEF.SVRCONN" />

              </bean>

               

              And I try to connect the Topic to the a4j;push component :

               

              <a4j:push id="push" address="MyTopic" onerror="alert(event.rf.data)">

                       <a4j:ajax event="dataavailable" render="now2" execute="@none" />

              </a4j:push>

               

               

              But when I access to the xhtml page where this push is, I get the following error :

              javax.naming.NameNotFoundException: The Name com.ibm.mq.jms.MQTopicConnectionFactory@ee461ef0 is not bound to this context.

               

              So, the component doesn't seem to find the Topic.

               

              Did I do something wrong ?

              • 4. Re: Push with own JMS  queue
                Lukáš Fryč Master

                Jeremy, could you dig and post whole stacktrace of the exception thrown?

                 

                Not the topic, but connection factory wasn't found.

                I guess there could be problem with visibility, if you are using EAR packaging, is it your case?

                 

                It also seems interesting that name of the connection factory have hash of the instance as suffix: @ee461ef0

                • 5. Re: Push with own JMS  queue
                  Jérémy Caramelle Newbie

                  Here is the full stacktrace from Tomcat :

                   

                  GRAVE: "Servlet.service()" pour la servlet Faces Servlet a généré une exception

                  com.google.common.collect.ComputationException: javax.faces.FacesException: Le Nom com.ibm.mq.jms.MQTopicConnectionFactory@9d3f2441 n'est pas lié à ce Contexte

                            at com.google.common.collect.ComputingConcurrentHashMap$ComputingMapAdapter.get(ComputingConcurrentHashMap.java:397)

                            at org.richfaces.application.push.impl.jms.JMSTopicsContextImpl.createTopic(JMSTopicsContextImpl.java:281)

                            at org.richfaces.application.push.TopicsContext.getOrCreateTopic(TopicsContext.java:48)

                            at org.richfaces.application.push.impl.SessionImpl.createSubscriptions(SessionImpl.java:182)

                            at org.richfaces.application.push.impl.SessionImpl.subscribe(SessionImpl.java:177)

                            at org.richfaces.resource.PushResource.encode(PushResource.java:88)

                            at org.richfaces.resource.UserResourceWrapperImpl.encode(UserResourceWrapperImpl.java:188)

                            at org.richfaces.resource.ResourceHandlerImpl.handleResourceRequest(ResourceHandlerImpl.java:222)

                            at javax.faces.webapp.FacesServlet.service(FacesServlet.java:591)

                            at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)

                            at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)

                            at org.richfaces.webapp.PushFilter.doFilter(PushFilter.java:130)

                            at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)

                            at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)

                            at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)

                            at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)

                            at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:470)

                            at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)

                            at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)

                            at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)

                            at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)

                            at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)

                            at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)

                            at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)

                            at java.lang.Thread.run(Thread.java:619)

                  Caused by: javax.faces.FacesException: Le Nom com.ibm.mq.jms.MQTopicConnectionFactory@9d3f2441 n'est pas lié à ce Contexte

                            at org.richfaces.application.push.impl.jms.JMSTopicsContextImpl$1.apply(JMSTopicsContextImpl.java:207)

                            at org.richfaces.application.push.impl.jms.JMSTopicsContextImpl$1.apply(JMSTopicsContextImpl.java:195)

                            at com.google.common.collect.ComputingConcurrentHashMap$ComputingValueReference.compute(ComputingConcurrentHashMap.java:355)

                            at com.google.common.collect.ComputingConcurrentHashMap$ComputingSegment.compute(ComputingConcurrentHashMap.java:184)

                            at com.google.common.collect.ComputingConcurrentHashMap$ComputingSegment.getOrCompute(ComputingConcurrentHashMap.java:153)

                            at com.google.common.collect.ComputingConcurrentHashMap.getOrCompute(ComputingConcurrentHashMap.java:69)

                            at com.google.common.collect.ComputingConcurrentHashMap$ComputingMapAdapter.get(ComputingConcurrentHashMap.java:393)

                            ... 24 more

                  Caused by: javax.naming.NameNotFoundException: Le Nom com.ibm.mq.jms.MQTopicConnectionFactory@9d3f2441 n'est pas lié à ce Contexte

                            at org.apache.naming.NamingContext.lookup(NamingContext.java:770)

                            at org.apache.naming.NamingContext.lookup(NamingContext.java:140)

                            at org.apache.naming.SelectorContext.lookup(SelectorContext.java:130)

                            at javax.naming.InitialContext.lookup(InitialContext.java:396)

                            at org.richfaces.application.push.impl.jms.JMSTopicsContextImpl$JMSTopicContext.createConnection(JMSTopicsContextImpl.java:98)

                            at org.richfaces.application.push.impl.jms.JMSTopicsContextImpl$JMSTopicContext.start(JMSTopicsContextImpl.java:123)

                            at org.richfaces.application.push.impl.jms.JMSTopicsContextImpl$1.apply(JMSTopicsContextImpl.java:199)

                            ... 30 more

                   

                  I'm on a local server and I don't use EAR packaging

                   

                  I've also modified the web.xml putting following parameters :

                   


                  <context-param>


                  <param-name>org.richfaces.push.jms.connectionFactory</param-name>


                  <param-value>#{jmsConnectionFactory}</param-value>

                  </context-param>

                   

                   


                  <context-param>


                  <param-name>org.richfaces.push.jms.topicsNamespace</param-name>


                  <param-value>/</param-value>

                  </context-param>

                   

                  Thanks for taking time to look at my problem

                  • 6. Re: Push with own JMS  queue
                    Lukáš Fryč Master

                    Ah, yeah, it's a little bit tricky to understand since the your language is unfamiliar to me,

                    but it can't simply find the connection factory you have provided using #{jmsConnectionFactory}.

                     

                    it seems this expressions evaluates to com.ibm.mq.jms.MQTopicConnectionFactory@9d3f2441,

                    but it can't be find in InitialContext.

                    • 7. Re: Push with own JMS  queue
                      Jérémy Caramelle Newbie

                      Hello,

                       

                      I've finally well configured my Topic and my ConectionFactory to make them accessible from the a4j:push component.

                       

                      I've package my web app in a EAR and deployed it on a Websphere Application Server 7.

                      The web app is deployed and started without any error.

                       

                      In a java class I've put the Richfaces example to publish messages in a topic :

                      TopicConnection connection; 
                      TopicSession session;
                      TopicPublisher publisher; 
                      public void sendCurrentDate() throws JMSException {
                          String currentDate = new Date().toString();
                          ObjectMessage message = session.createObjectMessage(message);
                          publisher.publish(message);
                      } 
                      // messaging needs to be initialized before using method #sendCurrentDate()
                      private void initializeMessaging() throws JMSException, NamingException {
                          if (connection == null) {
                              TopicConnectionFactory tcf = (TopicConnectionFactory) InitialContext.doLookup("java:/ConnectionFactory");
                              connection = tcf.createTopicConnection();
                          }
                          if (session == null) {
                              session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
                          }
                          if (topic == null) {
                              topic = InitialContext.doLookup("topic/datePush");
                          }
                          if (publisher == null) {
                              publisher = session.createPublisher(topic);
                          }

                       

                      In my xhtml file I've also put the example :

                      <a4j:push id="datePush" address="datePush"
                                  ondataavailable="jQuery(#{rich:element('serverDate')}).text(event.rf.data)" />
                                 
                      <a4j:outputPanel id="serverDate" layout="block">
                          <i>waiting for event...</i>
                      </a4j:outputPanel>

                       

                      So, I've several problems :

                           - When I call more than one time the sendCurrentDate() method, I get a javax.jms.IllegalStateException : Session closed

                           - The panel is never updated, the push component doesn't seem to see any message in the Topic.

                       

                      Maybe the problem comes from my ConnectionFactory settings in Websphere.

                      For the connectionFactory I've found these parameters :

                      connectionFactory.png

                      connectionFactory2.png

                      And for the Topic :

                      Topic.png

                      So I think that the root problem is that session closed exception but I can't find how to configure the WAS to avoid it.

                       

                      Thanks for your answers.

                       

                      Jérémy

                      • 8. Re: Push with own JMS  queue
                        Jérémy Caramelle Newbie

                        I got a detailed log of the exception :

                         

                        FFDC Exception:com.ibm.msg.client.jms.DetailedIllegalStateException

                        SourceId:com.ibm.ejs.jms.JMSMessageConsumerHandle.receive ProbeId:221

                        Reporter:com.ibm.ejs.jms.JMSMessageConsumerHandle@1f031f03

                        com.ibm.msg.client.jms.DetailedIllegalStateException: JMSCC0032: This message consumer

                        is closed. An application called a method that must not be used after the

                        message consumer is closed. Ensure that the message consumer is not closed before

                        calling the method.

                                at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Methoda

                        t sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccesso

                        rImpl.java:56)

                                at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingC

                        onstructorAccessorImpl.java:39)

                                at java.lang.reflect.Constructor.newInstance(Constructor.java:527)

                                at com.ibm.msg.client.commonservices.j2se.NLSServices.createException(NL

                        SServices.java:313)

                                at com.ibm.msg.client.commonservices.nls.NLSServices.createException(NLS

                        Services.java:388)

                                at com.ibm.msg.client.jms.internal.JmsErrorUtils.createException(JmsErro

                        rUtils.java:104)

                                at com.ibm.msg.client.jms.internal.State.checkNotClosed(State.java:145)

                                at com.ibm.msg.client.jms.internal.JmsMessageConsumerImpl.receive(JmsMes

                        sageConsumerImpl.java:394)

                                at com.ibm.mq.jms.MQMessageConsumer.receive(MQMessageConsumer.java:228)

                                at com.ibm.ejs.jms.JMSMessageConsumerHandle.receive(JMSMessageConsumerHa

                        ndle.java:444)

                                at org.richfaces.application.push.impl.jms.JMSTopicsContextImpl$JMSTopic

                        Context$1.run(JMSTopicsContextImpl.java:131)

                                at java.lang.Thread.run(Thread.java:736)

                        • 9. Re: Push with own JMS  queue
                          Jérémy Caramelle Newbie

                          Hello,

                           

                          After some tests, I've verified that I correctly send messages to the topic.

                          I can read these messages with a manually created durable subscriber :

                           

                               try {

                                                        consumer = session.createDurableSubscriber(topic,"mySubscriber");

                                                        connection.start();

                                         Message msg;

                                                        System.out.println("Waiting message...");

                                                        msg = consumer.receive();

                                                        System.out.println("Message received !");

                                                        System.out.println("New message : "+msg.toString());

                           

                           

                                              }catch(JMSException e){

                                                        e.printStackTrace();

                                                        System.out.println("Erreur receive consumer !!");

                                              }

                           

                          I can see the sent message in the SystemOut.log.

                           

                          But the Richfaces push component still doesn't see the message and the push event isn't processed.

                           

                          The JNDI name of my topic is jms/TBDTopicEFF7

                          My push component is declared like that :

                           

                            <a4j:push id="pushPanel" address="TBDTopicEFF7"

                                                                       ondataavailable="jQuery(#{rich:element('serverDate')}).text(event.rf.data)"

                                                                       onerror="alert(event.rf.data)">

                                                        </a4j:push>

                           

                           

                            <a4j:outputPanel id="serverDate" layout="block">

                                                                       <i>waiting for event...</i>

                                                        </a4j:outputPanel>

                           

                          And the topic namespace is correctly declared in my web.xml :

                           


                          <context-param>


                          <param-name>org.richfaces.push.jms.topicsNamespace</param-name>


                          <param-value>jms</param-value>

                          </context-param>

                           

                          The push functionnality works perfectly with the TopicContext functionnality but I need to bind the push component to my own topic.

                          Why ? Because a message will be send to my topic from a MDB (in the same EAR).

                           

                          If someone have an idea why the push component doesn't react when a message arrives into the topic, him help will be apreciated.

                           

                          Thanks for your repplies.

                           

                          Jérémy