4 Replies Latest reply on Apr 3, 2017 1:25 PM by Cheng Fang

    Jndi JMS destination creation

    Richard Moore Master

      I am new to queues and am having a problem understanding what is taking place in the creation of the connection, session, and destination in the JmsItemReaderWriterBase code. I created a standalone JMS java class for MQ and it creates the destination by way of -

       

      MQQueueConnectionFactory mqQueueConnectionFactory = new MQQueueConnectionFactory();

      mqQueueConnectionFactory.setHostName(FrameworkQueueTest.CONNECTION_HOST);

      mqQueueConnectionFactory.setChannel(FrameworkQueueTest.CHANNEL);

      mqQueueConnectionFactory.setPort(FrameworkQueueTest.CONNECTION_PORT);

      mqQueueConnectionFactory.setQueueManager(FrameworkQueueTest.QUEUE_MANAGER);

      mqQueueConnectionFactory.setTransportType(JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);

      QueueConnection connection = mqQueueConnectionFactory.createQueueConnection();

      connection.start();

      Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);

      Destination destination = session.createQueue(FrameworkQueueTest.QUEUE_NAME);

       

      When the JmsItemReaderWriterBase code fires the open it attempts the destination lookup first. So how is a destination instantiated without the connection and session?

        • 1. Re: Jndi JMS destination creation
          Cheng Fang Master

          the lookup for jms connection factory and destination is for running your batch app inside Java EE environment, where these jms resources are typically managed by the application server.  If you look at the config file for Java EE application server (e.g., WildFly), you can see these server-managed resources and server-administrated objects are already declared and ready for use by application via lookup.  These resources are server-wide and shared between deployed apps.

           

          Another way to obtain these jms resources is to inject them with CDI @Inject.  This works in either Java SE or Java EE environment.  In Java SE environment, some other class in your batch application knows how to create these resources and declare a producer method (method annotated with cdi @Produces).

          • 3. Re: Jndi JMS destination creation
            Richard Moore Master

            Well, it must be one of those days. I'm lost.

             

            In the JSL I use <reader ref="jmsItemReader">

            I am running in a stand-alone environment where I implemented my own JNDI, since I didn't have a server. I can return a jms connection and destination for the JmsItemReaderWriterBase. But I am totally confused on when the JNDI lookup takes place for the destination first then the connection when you need a connection and then a session in order to get the destination. Is there additional class(es) (like the MessageResourceProducer) that must be written by the developer to use the jmsItemReader? If so, how do these get used by the jmsItemReader? Below is what I currently have in use but how do I integrate this for Jberet to use?

             

            Context jms/qcf/javabTest -

            resource.type=javax.jms.Connection

            javax.jms.port=2221

            javax.jms.host=batappqa

            javax.jms.channel=CLIENT.RMOORE

            javax.jms.queue.manager=AISJBQ

            javax.jms.transport.type.class=com.ibm.msg.client.wmq.v6.jms.internal.JMSC

            javax.jms.transport.type.name=MQJMS_TP_CLIENT_MQ_TCPIP

            javax.jms.factory.initial=com.ibm.mq.jms.MQQueueConnectionFactory

             

            Context jms/queue/javabTest -

            resource.type=javax.jms.Destination

            javax.jms.queue.name=RICHARD_JAVA_BENCHMARK_PUT

             

            Supporting JNDI code for the resource type of javax.jms.Connection -

            MQQueueConnectionFactory mqQueueConnectionFactory = new MQQueueConnectionFactory();

            mqQueueConnectionFactory.setHostName(CONNECTION_HOST);

            mqQueueConnectionFactory.setChannel(CHANNEL);

            mqQueueConnectionFactory.setPort(CONNECTION_PORT);

            mqQueueConnectionFactory.setQueueManager(QUEUE_MANAGER);

            mqQueueConnectionFactory.setTransportType(JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);

            Connection connection = mqQueueConnectionFactory.createQueueConnection();

             

            Supporting JNDI code for the resource type of javax.jms.Destination -

            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

            Destination destination = session.createQueue(QUEUE_NAME);

            • 4. Re: Jndi JMS destination creation
              Cheng Fang Master

              The following is copied from job.xml in test-apps/amqp (see links above):

              <reader ref="jmsItemReader">
                <properties>
                 <!--<property name="connectionFactoryLookupName" value="/cf"/>-->
                <!--<property name="destinationLookupName" value="/queue/queue1"/>-->
                <!-- wait for 2 seconds for any more messages -->
                 <property name="receiveTimeout" value="2000"/>
                <property name="messageSelector" value=""/>
                <property name="sessionMode" value="DUPS_OK_ACKNOWLEDGE"/>
                </properties>
              </reader>

              If you already have the jndi lookup name for queue connection factory and queue, then use them as the value for connectionFactoryLookupName and destinationLookupName batch property.  And you don't need to implement any CDI producer classes.

               

              In the above example, the 2 batch properties are commented out, because that test app implements a CDI producer class to supply the queue connection factory and queue to JmsItemReader.

               

              To answer your question about the order in which jms session, connection, connection factory and queue are created, inside a managed environment (whether Java EE or your own jndi implementation), there are certain flexibility in creating and managing these resources, as long as they meet the requirement.  For instance, the server may very well implement a lazy-loading queue object proxy that is activated upon the first operation. 

               

              Also the session that created the queue may be a different session than the session used to service your business operation.  The server can have an internal session first, used to create multiple queue instances, which are returned to lookup request.