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).
see the following jms reader writer test for example,
There is also a test-apps/amqp jsr352/test-apps/amqp at master · jberet/jsr352 · GitHub
that uses all these.
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 -
Context jms/queue/javabTest -
Supporting JNDI code for the resource type of javax.jms.Connection -
MQQueueConnectionFactory mqQueueConnectionFactory = new MQQueueConnectionFactory();
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);
The following is copied from job.xml in test-apps/amqp (see links above):
<!--<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"/>
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.