title: JBoss AS7 hangs after MDB lock
body: <p>I'm currently getting an intermittent exception in JBoss AS7 that, unfortunately, I cannot yet reproduce.</p>
  
  <p>We are currently running two applications that are basically set as producer/consumer of JMS messages. We are using the default HornetQ configuration and a pool of 5 MDBs.</p>
  
  <p>Both applications starts doing ok, sending and receiving messages as expected. But after a while, all MDBs get locked (they each get a message but do not finish processing) and JBoss hangs some time after that showing the following message every ten minutes:</p>
  
  <pre><code>[org.jboss.ejb3.invocation] (Thread-21081 (HornetQ-client-global-threads-1636833629)) JBAS014134: EJB Invocation failed on component MyMessageListener for method public abstract void javax.jms.MessageListener.onMessage(javax.jms.Message): javax.ejb.EJBException: JBAS014516: Failed to acquire a permit within 10 MINUTES
  </code></pre>
  
  <p>From JBoss code in jarvana, it seems as if this error is set if a semaphore cannot be acquired:</p>
  
  <pre><code> /**
   * Get an instance without identity.
   * Can be used by finders,create-methods, and activation
   *
   * @return Context /w instance
   */
  public T get() {
      try {
          boolean acquired = semaphore.tryAcquire(timeout, timeUnit);
          if (!acquired)
              throw new EJBException("Failed to acquire a permit within " + timeout + " " + timeUnit);
      } catch (InterruptedException e) {
          throw new EJBException("Acquire semaphore was interrupted");
      }
  ...
  </code></pre>
  
  <p>The thing is, why the MDBs get locked? Shouldn't they timeout and continue processing? I've set the timeout to 5 minutes in standalone.xml file, but they never, ever seem to timeout.</p>
  
  <pre><code>&lt;session-bean&gt;
  &lt;stateless&gt;
     &lt;bean-instance-pool-ref pool-name="slsb-strict-max-pool"/&gt;
  &lt;/stateless&gt;
  &lt;stateful default-access-timeout="5000" cache-ref="simple"/&gt;
  &lt;singleton default-access-timeout="5000"/&gt;
  &lt;/session-bean&gt;
  </code></pre>
  
  <p>Does anyone know what could be happening?</p>
  
  <p>I would also, very gladly, accept any suggestions on how to simulate the problem or on other ways to set MDBs timeout.</p>
  
  <p>Any help would be appreciated.</p>
  
  <p>Thanks for your time.</p>
  
  <p><strong>Edit:</strong></p>
  
  <p>So I was finally able to reproduce the problem simply by sending the MessageListener to sleep for longer than the instance-acquisition-timeout. Following is the test code:</p>
  
  <pre><code>&lt;!-- standalone.xml --&gt;
  &lt;strict-max-pool name="mdb-strict-max-pool" max-pool-size="5" instance-acquisition-timeout="30" instance-acquisition-timeout-unit="SECONDS"/&gt;
  </code></pre>
  
  <p>MDB:</p>
  
  <pre><code>@MessageDriven(name = "TestMDB", activationConfig = {
      @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
      @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/myQueue"),
      @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge")//,
      })
  public class TestMDB implements MessageListener {
  
  private final static Logger LOGGER = Logger.getLogger(TestMDB.class
          .toString());
  
  @Resource 
  private MessageDrivenContext ctx;
  
  private final static int sleepingTime = MyProperties.SLEEP_MILLISECS; 
  
  /**
   * @see MessageListener#onMessage(Message)
   */
  public void onMessage(Message rcvMessage) {
      ObjectMessage msg = null;
      Future&lt;String&gt; future = null;
      MyResource res = null;
  
      try {
          if (rcvMessage instanceof ObjectMessage) {
              msg = (ObjectMessage) rcvMessage;
              res = (MyResource)msg.getObject();
  
              LOGGER.info("Received resource: " + res);
              Thread.sleep(sleepingTime);
              LOGGER.info("Released resource: " + res);
          } else {
              LOGGER.warning("Message of wrong type: "
                      + rcvMessage.getClass().getName());
          }
      } catch (JMSException e) {
          throw new RuntimeException(e);
      } catch (InterruptedException e) {
          throw new RuntimeException(e);
      }
  }
  }
  </code></pre>