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

    Jndi JMS destination creation

    richardmoore

      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
          cfang

          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).

          • 2. Re: Jndi JMS destination creation
            cfang
            • 3. Re: Jndi JMS destination creation
              richardmoore

              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
                cfang

                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.