JMS Advanced Experienced Freshers Interview Questions Answers

What can be the likely cause of the “javax.naming.NameNotFoundException: MyQueueConnectionFactory” not found error?

The error detail of the above error is as follows:
Initiating login ...
Binding name:`java:comp/env/jms/QueueName `
Binding name:`java:comp/env/jms/MyQueueConnectionFactory `
JNDI lookup failed: javax.naming.NameNotFoundException: MyQueueConnectionFactory not found
Unbinding name:`java:comp/env/jms/QueueName `
Unbinding name:`java:comp/env/jms/MyQueueConnectionFactory `

If the user notices properly there are extra spaces after the queue name and the myqueueconnectionfactory quotes. The deploytool regards any extra space defined by the user as a part of the name. Due to this the deploytool is not able to take the input properly.
To rectify this problem the user needs to make use of the Resource Refs tabbed pane to delete the extra space. Once the extra spaces are deleted and the application is saved upon redeployment this error will not occur anymore.

What can be done to map the javax.jms.message & javax.mail.message?

The following steps can be performed to map the javax.jms.message with javax.mail.message:
Mapping to javamail domain from jms domain (To receive a javax.jms.Message):
- A JMS topic/queue is associated to multiple email id`s.

- Mapping the JMS Message Header to ‘custom’ JavaMail Message Header.

- Associating the JMS Message Body with the JavaMail Message body.

- The JavaMail client application can process these ‘custom’ headers and the content of the message body.
Mapping to jms domain from javamail(To receive a javax.mail.Message):

- An e-mail id can be associated with multiple JMS topics/queues.

- Mapping the JavaMail Message Header to a ‘custom’ JMS Message Header.

- Associating the JavaMail Message Body with the JMS Message body.

- The JMS client application will process these ‘custom’ headers and the content of the message body.

What is a MOM in reference to JMS?

Software components in a distributed computing network often need to pass messages between them. These are to be done asynchronously. The MOM or the message oriented middleware is a software that is placed between any two communicating components. A middleware is a component that is placed between the client and the server. The MOM provides the facility of message passing by using the technique of queuing. All the messages are stored in the form of queue till the client that requested it can read it. The basis of reading messages by the client can be by FIFO or priority. By using the concept of queuing the software components can work independently of time.

Describe briefly the components of the Java Messaging Service.

The JMS application comprises of the following components:

- JMS provider: This is the main messaging system which provides with the JMS interfaces. IT also provides with the panel to control administrative and control features.

- JMS clients: These comprise the programs and components which are written using the Java programming language. They are responsible for the production and consumption of messages.

- Messages: These are the objects that are used to communicate between two clients.

- Administered objects: These are predefined objects created by the administrator which can be used by the clients.

- Native clients: These are programs that do not use the JSM API client but instead uses its own native API client.

What is the reason of getting the “ Unable to get the internal JNDI context error “?

This type of error occurs when the user has incorrectly specified the client properties file. A good example of this is the user might have used the windows syntax in a unix system environment. It can also be caused when the correct path to the jms_client.properties file is not correct. The user also has to define the path to the config directory properly.

The error detail is shown as follows:

java -Djms.properties=%J2EE_HOME%\config\jms_client.properties SimpleQueueSender MyQueue 3
Queue name is MyQueue

SEVERE JMSInitialContext: Unable to get internal JNDI context because:
javax.naming.CommunicationException: Cannot connect to ORB [Root exception is
org.omg.CORBA.COMM_FAILURE: minor code: 1398079689 completed: No]
This error can be rectified by the user setting the classpath for the client application correctly.

What do you understand by JMS messaging domain?

The JMS domain provides an approach to messaging.

The JMS provides a user with two types of domains:

- Publish/subscribe domain
- Point to point domain

The point to point model enables the JMS clients to send and receive messages via virtual channels known as queues. The message generators are the senders and the message consumers are the receivers. They can be both synchronous and asynchronous. In the point to point model the messages are passed via the virtual channel known as topics. The message producers are called publishers whereas the receivers are known as subscribers.
The JMS specification is responsible for providing the settings and other restrictions for both the types of domains.

Under what arguments in non-transacted sessions are messages acknowledged?

Messages are acknowledged in non-transacted sessions on the basis of the second argument for the createQueueSession ot the createTopicSession method. The possible argument values can be:

- Session.AUTO_ACKNOWLEDGE: In this scenario the session acknowledges a client's receipt of a message automatically when the client has returned from a call to receive or in the scenario when the message listener called returns successfully.

- Session.CLIENT_ACKNOWLEDGE: In this method the client acknowledges a message by calling the acknowledge method of the message.

- Session.DUPS_OK_ACKNOWLEDGE: Whenever this option is used it simply instructs the session to acknowledge the delivery of a message. It should only be used by consumers who can tolerate duplication of messages.

What do you understand by the creation of durable subscriptions?

In case the user wants to make sure that the application should receive all the published messages the persistent mode of delivery of messages should be used. The method TopicSession.createSubscriber creates a non-durable subscriber when executed. The non-durable subscriber can only receive the messages that were published while the subscriber itself was active. Instead, if the method used was TopicSession.DurableSubscriber it will lead to the creation of a durable subscriber. The advantage of a durable subscriber is that it can receive the published messages that were published while it was not active. A durable subscriber is able to register a subscription that is durable. They can be recognized by unique identity that is retained by the JMS provider. A durable subscription would continue to exist and hold messages until the subscriber calls for an unsubscribe method.

Write the program to count the number of messages in a queue.

The code for counting the number of messages in a queue would be:
package PointToPoint;
import java.util.Enumeration;
import javax.naming.InitialContext;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.Message;
import javax.jms.QueueSession;
import javax.jms.QueueBrowser
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;

public class Browser
{
   public static void main(String[] args) throws Exception
   {

       InitialContext ctx = new InitialContext();

       Queue queue = (Queue) ctx.lookup("queue/queue0");

       QueueConnectionFactory connFactory = (QueueConnectionFactory) ctx.
lookup("queue/connectionFactory");

       QueueConnection queueConn = connFactory.createQueueConnection();

       QueueSession queueSession = queueConn.createQueueSession(false,
Session.AUTO_ACKNOWLEDGE);

       QueueBrowser queueBrowser = queueSession.createBrowser(queue);

       queueConn.start();

       Enumeration e = queueBrowser.getEnumeration();
       int numMsgs = 0;

       while (e.hasMoreElements())
       {
           Message message = (Message) e.nextElement();
           numMsgs++;
       }

       System.out.println(queue + " has " + numMsgs + " messages");

       queueConn.close();
   }
}


How can asynchronous messaging deadlocks be avoided?

Asynchronous messages in JMS can be deadlocked if the close() method of a session is inside a user level synchronized block. To prevent these deadlock from occurring the user must specify the close() method outside of the area of the user-synchronized block.
An example of a code snippet :
public class CloseTest()
{
   private void xxx()
   {
       synchronized (this)
       {
           create connection/session/consumer
           initialize and set a listener for this consumer;
           wait();
           connection.close();
       }
   }
   private void onMessage(Message message)
   {
       synchronized (this)
       {
           notify();
       }
   }
}

In the above example before the connection.close() method is closed, another message can be delivered to the onmessage routine. The monitor lock for the CloseTest method is owned by the main() method. Prior to the closetest sending a message the JMS sets the inlistener as the state. This will create the scenario of a deadlock in case the onMessage routine tries to get the access of the monitor lock.

How can a MDB transaction be rollbacked? Give example.

To rollback a transaction with the MDB the user can make use of the weblogic extension TXhelper which helps in automating the process of transaction rollbacks. The other approach can be to use the MDB context as reference to rollback.

For ex. Using the MDB context for rollbacks:
UserTransaction ut = weblogic.transaction.TXHelper.getUserTransaction();
ut.setRollbackOnly();

OR

private MessageDrivenContext context;
public void setMessageDrivenContext(MessageDrivenContext mycontext)
{
   context = mycontext;
}
public void onMessage(Message msg)
{
   try
   {
       // some logic
   }
   catch(Exception e)
   {
       System.out.println("MDB doing rollback");
       context.setRollbackOnly();
   }
}

Write a program to send a message to a queue.

The JMS has two primary models of messaging point to point and publish / republish. The queue is used in the point to point model.

The code for sending a message to a queue:

import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Queue;
import javax.jms.Session;

import org.springframework.jms.core.MessageCreator;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.JmsTemplate102;

public class JmsQueueSender
{
   private JmsTemplate jmsTemplate;

   private Queue queue;

   public void setConnectionFactory(ConnectionFactory cf)
   {
       jt = new JmsTemplate102(cf, false);
   }

   public void setQueue(Queue q)
   {
       queue = q;
   }

   public void simpleSend()
   {
       this.jmsTemplate.send(this.queue, new MessageCreator()
       {
           public Message createMessage(Session session) throws JMSException
           {
               return session.createTextMessage("hello queue world");
           }
       }
   }
}

What do you understand by the Event driven architecture?

The event driven architecture as the name suggests is built on the concept of processes and events which can be dynamic and complex. Whenever an action occurs in a system, the particular process sends an event to the entire system. This even states that an action took place. A single event can cause more processes to become active which in turn themselves can further give rise to more processes. A good example of the EDA can be seen in insurance management systems. Suppose if a user changes his address, this is considered as an event and the entire system is allowed to know that a user address change has occurred. This can lead to many changes in other parts/ domains of the system. This is managed by the EDA architecture. These systems use EDA as it can localize changes and does not require the implementation of a single large central processing engine.

What are the ways in which BytesMessage can be used?

The byte message is a special form of message which contains in itself a payload of primitive bytes. Since they carry bytes they can be used to transfer data between two communicating applications. The BytesMessage can also be useful when a JMS implementation is used just to act as a mode of transport between the systems. The message payload remains opaque to the client. When a primitive type is stored the information is converted into a byte representation and after it is stored as the payload in the bytemessage. The different data types stored cannot be differentiated from each other in this form of representation. Since no distinction can be made on the different types of data stored the chances of errors while reading the data can increase. It is always suggested that a payload be read in the same order as it was created by the sender.

What are the different ways in which the message delivery can be made more reliable?

The different ways in which the reliability of the message delivery system can be effected are:
- Controlling message acknowledgement: The user can specify different levels of control over acknowledgements.

- Specifying message persistence: The user can set the messages to be persistent so that they are not lost in case of failures.

- Setting priority levels: The user can set the priority of various messages.

- Message expiry: The user can set the expiration time for messages.

- Temporary destinations: The user can create temporary destinations which last only till the duration of the connection.

Write the code for an asynchronous class queue receiver.

The code for the asynchronous class queue receiver would be as follows:
package pointToPoint;
import javax.naming.InitialContext;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.Message;
import javax.jms.TextMessage;
import javax.jms.MessageListener;
import javax.jms.JMSException;
import javax.jms.ExceptionListener;
import javax.jms.QueueSession;
import javax.jms.QueueReceiver;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;

public class AsyncReceiver implements MessageListener, ExceptionListener
{
   public static void main(String[] args) throws Exception
   {
       InitialContext ctx = new InitialContext();

       Queue queue = (Queue) ctx.lookup("queue/queue0");

       QueueConnectionFactory connFactory = (QueueConnectionFactory) ctx.lookup("queue/connectionFactory");

       QueueConnection queueConn = connFactory.createQueueConnection();

       QueueSession queueSession = queueConn.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);

       QueueReceiver queueReceiver = queueSession.createReceiver(queue);

       AsyncReceiver asyncReceiver = new AsyncReceiver();
       queueReceiver.setMessageListener(asyncReceiver);
       queueConn.setExceptionListener(asyncReceiver);

       queueConn.start();

       System.out.print("waiting for messages");
       for (int i = 0; i < 10; i++)
       {
           Thread.sleep(1000);
           System.out.print(".");
       }
       System.out.println();

       queueConn.close();
   }

public void onMessage(Message message)
{
   TextMessage msg = (TextMessage) message;
   try
   {
       System.out.println("received: " + msg.getText());
   }
   catch (JMSException ex)
   {
       ex.printStackTrace();
   }
}

public void onException(JMSException exception)
{
   System.err.println("an error occurred: " + exception);
}
}

Write the code to create a session bean performing JMS operations.

A bean should always contain the code for the initialization of JMS administered objects to be used. To prevent the repetition of this code the user can make use of the ejbCreate method.

For ex. Code snippet for the usage of create method:
public class EjbCompBean implements SessionBean
{
   ...
   ConnectionFactory cf = null;
   Topic topic = null;

public void ejbCreate()
{
   ....
   ictx = new InitialContext();
   cf = (ConnectionFactory)
   ictx.lookup("java:comp/env/jms/conFactSender");
   topic = (Topic) ictx.lookup("java:comp/env/jms/topiclistener");
}
   ...
}

In what ways the clustering process can be improved?

Some of the better practices that can be used for clustering are:

- Minimization of the JMS client-side state: The user can perform work in the transacted sessions. Checkpoints and saves must be made for full recovery.

- Non-durable subscriptions to be avoided: The usage of non-durable subscriptions should be kept to a minimum.

- Avoid keeping durable subscriptions alive for long periods: The users should know the fact that only one durable subscription can be active at any given time. The load balancing and clustering leads to the creation of multiple application instances.The JMSexception method used prevents duplicate instances from executing and hence helps in maintaining an organized system.
Write the server side code for FAILOVER.

Below is the code snippet for a queue that is server side fail-over tolerant:
while (notShutdown)
{
   Context ctx = new InitialContext();

   QueueConnectionFactory qcf = (QueueConnectionFactory)
   ctx.lookup(QCF_NAME);
   Queue q = (Queue) ctx.lookup(Q_NAME);
   ctx.close();

   try
   {

       QueueConnection qc = qcf.createQueueConnection();
       QueueSession qs = qc.createQueueSession(true, 0);
       QueueSender snd = qs.createSender(q);
       QueueReceiver rcv = qs.createReceiver(q);

       qc.start();

       while (notDone)
       {
           Message request = rcv.receive();
           Message reply = qs.createMessage();

           snd.send(reply);
           qs.commit();
       }

       qc.stop();
   }
   catch (JMSException ex)
   {
       if (transientServerFailure)
       { // retry }
       else
       {
           notShutdown = false;
       }
   }
}

What are the possible ways to set aside a message and then acknowledge it later?

By default there are no primitives defined for performing such actions. Although there can be two possible solutions:

- Multiple session usage:
The user can set aside a message and acknowledge it later by using the following code snippet:
while (true)
{
   Create a session, subscribe to one message on durable subscription
   Save session reference in memory
   To acknowledge the message, find the session reference and call
   acknowledge() on it.
}

- Suspend work:
The user can use another approach where the transactions are used and the work is suspended. Code snippet:
start transaction
while(true)
{
   message = receive();
   if (message is one that I can handle)
   process the message
   commit
}
else
{
   suspend transaction
   put transaction aside with message
   start transaction
}

Post a Comment

Previous Post Next Post