Yes. I´m still writing a post with a sequence diagram to explain better.
To be short:
At the line where I worte // A JMSConsumer is created to retrieve exchange object when MDB end
there´s lot of statements and one of that is a call to javax.jms.MessageConsumer.receive() method. However, when the producer sent the message it set a Time To Live in my jms message. This TTL was 20 seconds. As my MDB connect to a third party webService that hangs more than 30 seconds sometimes, my jms message died before MDB acks the comsumption. Meanwhile, the javax.jms.MessageConsumer.receive() method is waiting for a message that should never come because the jms message relies in DLQ now. So, javax.jms.MessageConsumer.receive() method will wait forever and an available MyWorkerBean
instance in my pool (annotated as @Pool(value = PoolDefaults.POOL_IMPLEMENTATION_STRICTMAX, maxSize = 30)
) will be decreased. You can see this decreasing in jmx-console, menu j2ee.
The solution was set a TTL for MessageConsumer.receive() method. So today my code looks like this:
@Clustered
@Local(MyWorkerInterface.class)
@Stateless(name = "MyWorkerBean")
@Interceptors(value = { SpringBeanAutowiringInterceptor.class, LoggingInterceptor.class })
@RolesAllowed(value = "client")
@Pool(value = PoolDefaults.POOL_IMPLEMENTATION_STRICTMAX, maxSize = 30)
public class MyWorkerBean implements MyWorkerInterface {
@RolesAllowed("client")
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public WorkResponse execute(final WorkRequest workRequest) {
long start = System.currentTimeMillis();
WorkExchange exchange = new WorkExchange();
exchange.setWorkRequest(workRequest);
// A JMSProducer is created to send exchange to a JMS queue
// A MDB class retrieve data from a third party webservice (expensive operation taking between 300 to 60000ms to finish) using WorkExchange.workRequest fields
...
ObjectMessage responseMessage
= (ObjectMessage
) messageConsumer.receive(20000);
...
LoggerUtil.info("Operation time: " + (System.currentTimeMillis() - start));
// WorkExchange.workResponse have been set by MDB
WorkResponse response = exhange.getWorkResponse();
return response;
}
}
[]s