Domanda

i have a stateless ejb, and in that i make a connection with a jms queue and send message to it.
Part of the code where i do this:

@Resource(mappedName = "jms/abcd")
private ConnectionFactory abcd;
@Resource(mappedName = "jms/xyz")
private Queue xyz;
 @Override
    public void saveCounter(String protocolName, String serialNumber, String counterName,CounterAction action)
    {
        Connection connection = null;
        Session session=null;
        try
        {
            connection = abcd.createConnection();
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            MessageProducer producer = session.createProducer(xyz);

            Message message = session.createMessage();
            message.setStringProperty("serialNumber", serialNumber);
            producer.send(message);
        }
        catch (Exception e)
        {
            logger.error("Sending message to queue", e);
        }
        finally
        {
            try
            {
                if(session!=null){
                    session.close();    
                }
                if (connection != null)
                {
                    connection.close();
                }
            }
            catch (JMSException e)
            {
                logger.warn(e);
            }
        }

    }

I am using MDB. The consumer code is as shown:

 @MessageDriven(name = "XXMessageDrivenBean", activationConfig = {
 @ActivationConfigProperty(propertyName = "destinationType",
 propertyValue = "javax.jms.Queue") }, mappedName = "jms/xyz")

 public class CounterMessageDrivenBean {

 ...

     @Override
     public void onMessage(Message message){

        System.out.println("got message: " + message);
            log.debug("got message: " + message);

     }

     .....
 }

I use the functionality of this ejb from other ejbs, by doing dependency injection of this ejb and calling its method. It works fine for some requests

But when i try to do load test of my code, after some number of requests like thousand, the crateConnection part of the code starts to fail with exception:

Thread 64518 "httpWorkerThread-38080-1": (state = BLOCKED)
    at com.sun.enterprise.resource.AbstractResourcePool.getResourceFromPool(AbstractResourcePool.java:788)
    at com.sun.enterprise.resource.AbstractResourcePool.getUnenlistedResource(AbstractResourcePool.java:682)
    at com.sun.enterprise.resource.AbstractResourcePool.internalGetResource(AbstractResourcePool.java:624)
    at com.sun.enterprise.resource.AbstractResourcePool.getResource(AbstractResourcePool.java:470)
    at com.sun.enterprise.resource.PoolManagerImpl.getResourceFromPool(PoolManagerImpl.java:248)
    at com.sun.enterprise.resource.PoolManagerImpl.getResource(PoolManagerImpl.java:176)
    at com.sun.enterprise.connectors.ConnectionManagerImpl.internalGetConnection(ConnectionManagerImpl.java:323)
    at com.sun.enterprise.connectors.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:245)
    at com.sun.enterprise.connectors.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:175)
    at com.sun.enterprise.connectors.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:168)
    at com.sun.messaging.jms.ra.ConnectionFactoryAdapter._allocateConnection(ConnectionFactoryAdapter.java:179)
    at com.sun.messaging.jms.ra.ConnectionFactoryAdapter.createConnection(ConnectionFactoryAdapter.java:166)
    at com.sun.messaging.jms.ra.ConnectionFactoryAdapter.createConnection(ConnectionFactoryAdapter.java:148)

at above code shown : saveCounter : createConnection

Please help me to understand why my code starts to fail. I am glassfish application server.

Thanks in advance

È stato utile?

Soluzione 4

I have found out that closing the connection, closes the session and producer too. So there is no issue related to open resources.

The issue that i have found out is that, we are putting too much load on the jms, its like 1 lack per hour. So jms service is not able to handle so much load.

Altri suggerimenti

Himanshu,

The first thing that comes to mind is why are you using a stateless ejb for this functionality and not MDB.

The negative bits about your code is you are handling opening and closing of the JMS connections.

If you were using MDB, the JMS connection handling is handled by MDB itself. Plus you will get a pool of JMS connections opened which can be tuned easily. Thus you should not run into the same issue that you have reported.

You might try also closing the MessageProducer object. Your code looks pretty good for closing the session and connection, but you don't actually close the producer. MessageProducer javadoc recommends calling the close(). You could put the call to producer.close(); right after the producer.send(message);.

Also, minor suggestion on finally block - if the session.close() throws an exception you won't get to close the connection. You may also try wrapping that call in try/catch block:

 finally
    {
        try
        {
            if(session!=null){
               try {
                  session.close();    
                } catch(JMSException e) { }
            }
            if (connection != null)
            {
                connection.close();
            }
        }
        catch (JMSException e)
        {
            logger.warn(e);
        }
    }

Hope this helps!

I am using very similar code for processing 200,000-300,000 trx each day and not facing any problem. Here I am sharing the code: ...

Connection connection;
Session session = null;
MessageProducer messageProducer;
try {
    connection = connectionFactory.createConnection();

    session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    messageProducer = session.createProducer(queue);
    TextMessage message = session.createTextMessage();

    for (String msgKey : messages.keySet()) {

        message.setText(messages.get(msgKey));
        // logger.debug("Sending message to Queue: "
        // + message.getText());
        messageProducer.send(message);
    }
} catch (JMSException e) {
    logger.info("Error " + e);
    e.printStackTrace();
}

...

The only difference that I can see from your code is that I am declaring the MessageProducer outside the try block. Try to see if it makes a difference.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top