6 Replies Latest reply on Dec 18, 2008 9:22 AM by rododendro.ivan

    javax.jms.Session and JMS XAConnectionFactory

    rododendro.ivan

      Hello,
      we have a SLSB who register himself as producer of a topic, in post construct we create Conection, Session & Porducer, and in send() we call session.createObjectMessage():


      @PostConstruct
       public void postConstruct() {
       try {
       connection = connectionFactory.createTopicConnection();
       session = connection.createSession(true, Session.SESSION_TRANSACTED);
       producer = session.createProducer(destination);
       producer.setTimeToLive(messageValidityPeriod * 60000);
       } catch (final JMSException e) {
       logger.error("unable to create JMS producer", e);
       }
       }
      
      
      public void send(final Map<String, String> properties, final ProvisioningEvent event) {
       try {
       final ObjectMessage message = session.createObjectMessage();
      
       message.setObject(event);
      
       [...]
      
       producer.send(message);
      
       } catch (final JMSException e) {
       if (logger.isInfoEnabled()) {
       logger.info("JMSException: " + e.getMessage());
       }
       }
       }
      


      Connetction Factory is JmsXA.

      It worked in JBAS50-CR2 (JBM 1.4.1-CR1 ?), but with JBAS5.0-GA it does not work anymore:

      Code:
      javax.jms.IllegalStateException: The session is closed


      on calling session.createObjectMessage() in method send().

      If the session is created in the method send, performances are really slowed down, due to a synchronization problem.

      Please help
      Ivan

        • 1. Re: javax.jms.Session and JMS XAConnectionFactory

          What you are doing is an anti-pattern
          You shouldn't have one connection per ejb instance that is very inefficient.
          You should pool the connections/sessions in the send() method.

          i.e. open and close them as you need them.


          If the session is created in the method send, performances are really slowed down, due to a synchronization problem.


          You'll need to explain that. java:/JmsXA is already a pool of pre-constructed connections/sessions.
          The only synchronization problem I can think of is if your pool is too small
          for the number of concurrent requests.
          e.g. 100 front end web threads trying to share 20 jms connections

          The reason for the change in behaviour is that ejb3 is now integrated with
          the JCA CachedConnectionManager which spots the anti-pattern and closes
          the unclosed connection (really just the handle not the real underlying connection) .
          and issues a warning.

          Setting DEBUG=false in jca-jboss-beans.xml will stop JBoss checking for the anti-pattern.

          • 2. Re: javax.jms.Session and JMS XAConnectionFactory
            rododendro.ivan

            Ok, I see the anti-pattern, thank you.

            I changed my implementation :

            public void notify(final Map<String, String> properties, final ProvisioningEvent event) {
             Connection connection = null;
             Session session = null;
             MessageProducer producer = null;
            
             try {
             connection = connectionFactory.createTopicConnection();
             session = connection.createSession(true, Session.SESSION_TRANSACTED);
             producer = session.createProducer(destination);
             producer.setTimeToLive(messageValidityPeriod * 60000);
            
             ObjectMessage message = session.createObjectMessage();
            
             message.setObject(event);
            
             [...]
            
             producer.send(message);
            
             } catch (final JMSException e) {
             [...]
            
             throw new ApplicativeRuntimeException(e);
             } finally {
             try {
             if (producer != null)
             producer.close();
            
             if (session != null)
             session.close();
            
             if (connection != null)
             connection.close();
             } catch (JMSException e) {
             logger.error("JMSException while closing JMS Connection", e);
             }
             }
             }


            and nothing is done in PostConstruct method.

            Doing this I get about 40% monitor time on worker threads:


            "WorkerThread#5[10.10.164.139:2106]" - Thread t@129
             java.lang.Thread.State: BLOCKED on java.lang.Class@14ab043 owned by: WorkerThread#1[10.10.164.139:2102]
             at java.beans.PropertyEditorManager.findEditor(PropertyEditorManager.java:75)
             at org.jboss.util.propertyeditor.PropertyEditors.mapJavaBeanProperties(PropertyEditors.java:369)
             at org.jboss.remoting.util.SecurityUtility.mapJavaBeanProperties(SecurityUtility.java:809)
             at org.jboss.remoting.transport.socket.SocketServerInvoker.setup(SocketServerInvoker.java:204)
             at org.jboss.remoting.transport.bisocket.BisocketServerInvoker.setup(BisocketServerInvoker.java:651)
             at org.jboss.remoting.ServerInvoker.create(ServerInvoker.java:949)
             at org.jboss.remoting.transport.Connector.init(Connector.java:432)
             at org.jboss.remoting.transport.Connector.create(Connector.java:1139)
             at org.jboss.remoting.transport.Connector.start(Connector.java:312)
             at org.jboss.remoting.Client.addListener(Client.java:982)
             at org.jboss.jms.client.remoting.JMSRemotingConnection.addInvokerCallbackHandler(JMSRemotingConnection.java:259)
             at org.jboss.jms.client.remoting.JMSRemotingConnection.start(JMSRemotingConnection.java:375)
             at org.jboss.jms.client.delegate.ClientConnectionFactoryDelegate.org$jboss$jms$client$delegate$ClientConnectionFactoryDelegate$createConnectionDelegate$aop(ClientConnectionFactoryDelegate.java:158)
             at org.jboss.jms.client.delegate.ClientConnectionFactoryDelegate$createConnectionDelegate_N3019492359065420858.invokeTarget(ClientConnectionFactoryDelegate$createConnectionDelegate_N3019492359065420858.java)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:111)
             at org.jboss.jms.client.container.StateCreationAspect.handleCreateConnectionDelegate(StateCreationAspect.java:81)
             at org.jboss.aop.advice.org.jboss.jms.client.container.StateCreationAspect_z_handleCreateConnectionDelegate_28191855.invoke(StateCreationAspect_z_handleCreateConnectionDelegate_28191855.java)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
             at org.jboss.jms.client.delegate.ClientConnectionFactoryDelegate.createConnectionDelegate(ClientConnectionFactoryDelegate.java)
             at org.jboss.jms.client.JBossConnectionFactory.createConnectionInternal(JBossConnectionFactory.java:205)
             at org.jboss.jms.client.JBossConnectionFactory.createTopicConnection(JBossConnectionFactory.java:115)
             at org.jboss.jms.client.JBossConnectionFactory.createTopicConnection(JBossConnectionFactory.java:109)
             at com.gemalto.srm.impl.event.EventNotificationSessionBean.notify(EventNotificationSessionBean.java:69)


            Where am I wrong?

            Thank you again
            Ivan

            • 3. Re: javax.jms.Session and JMS XAConnectionFactory
              rododendro.ivan

              EventNotificationSessionBean line 69:

              connection = connectionFactory.createTopicConnection();



              • 4. Re: javax.jms.Session and JMS XAConnectionFactory
                rododendro.ivan

                About connection pool:

                I set min-pool-size to 10, max-pool-size to 20 and I have only 10 threads client side.

                • 5. Re: javax.jms.Session and JMS XAConnectionFactory

                   

                  "ivan.rododendro" wrote:

                  at org.jboss.jms.client.JBossConnectionFactory.createTopicConnection(JBossConnectionFactory.java:109)
                  at com.gemalto.srm.impl.event.EventNotificationSessionBean.notify(EventNotificationSessionBean.java:69)
                  


                  Where am I wrong?


                  This shows you using the JBoss Messaging client connection factory directly
                  not the jms connection pool.

                  So you are creating a new jms connection everytime.

                  It also won't understand any XA transaction.

                  • 6. Re: javax.jms.Session and JMS XAConnectionFactory
                    rododendro.ivan

                    You are definitely right, I was doing some tests without XA and I forgot to set the connection factory back to "JmsXA". There's no synchronization problem with XA Connection Factory.

                    Thank you very much for have helped me.

                    Ivan