0

I've got an MDB which consumes messages from a queue, and then invokes a stateless EJB to perform some db operations. Something like this:

public class TestMDB implements MessageListener
{
  @EJB
  private UpdateService updateSvc;

  @Override
  public void onMessage(Message message) 
  {
    try
    {
      updateSvc.updateSystemStatuses();
    }
    catch(Exception e)
    {
      // log error
    }
  }
}

In the code above, if the updateSystemStatuses() call throws a RuntimeException, this seems to cause a memory leak. I've accelerated the process by inducing updateSystemStatuses() to throw RuntimeExceptions, and when this happens CPU usage and memory usage spike (as observed in JVisualVM) until I start to get OutOfMemoryErrors.

If I modify the code to throw the RuntimeExceptions out of onMessage, the resource leak seems to go away completely:

public class TestMDB implements MessageListener
{
  @EJB
  private UpdateService updateSvc;

  @Override
  public void onMessage(Message message) 
  {
    try
    {
      updateSvc.updateSystemStatuses();
    }
    catch(RuntimeException e)
    {
      //log error
      throw e;
    }
    catch(Exception e)
    {
      //log error
    }
  }
}

I'm aware that throwing a RuntimeException out of an EJB method will cause a transaction rollback, and I assume that has something to do with what I'm seeing, but beyond that I'm not clear on what's going on here. Is the resource leak a Glassfish bug? Am I handling exceptions in my MDB the correct way?

I'm running Glassfish 3.1.2.2 on Java 1.6.0_35, using Eclipselink and Oracle 11G.

Sklivvz
  • 30,601
  • 24
  • 116
  • 172
Jeff
  • 227
  • 4
  • 17

1 Answers1

0

I think that you are facing a "poison message" situation. Your MDB fetches a message in the queue and tries to process it. Because the processing fails (you throw an exception), the message is put back in the queue. And processed again, and again, and again. That's why you see CPU go through the roof.

With Glassfish, you can specify how many times a message can be processed, before being ignored (that is, if the processing throws an exception). You will find useful information on this blog:

http://weblogs.java.net/blog/felipegaucho/archive/2009/09/24/handling-poison-messages-glassfish

Olivier Liechti
  • 3,138
  • 2
  • 19
  • 26