javajbossjmsactivemq-artemisjboss-mdb

JBoss EAP 7.1: ActiveMQ configuration - MDB with properties JMS not consuming message


I work with JBoss EAP 7.1 (Wildfly) and have problem with configuration of queue via standalone-full.xml (ActiveMQ)

In my web application there are many MDBs with property selector: property set in header of JMS message. If the message does not have the correct property set (or no property) it remains blocked on the queue and does not go to any DLQ or Expiry Queue. Why is this? Why is it not being consumed? I have set standalone-full.xml with custom DLQ, one for any queue associated with it own MDB. It is possible to force this message to go in any other queue?

Here is the relevant XML from standalone-full.xml:

<subsystem xmlns="urn:jboss:domain:messaging-activemq:2.0">
   ...
   <address-setting name="#" page-size-bytes="2097152" max-size-bytes="10485760" expiry-address="jms.queue.ExpiryQueue" dead-letter-address="jms.queue.DLQ"/>
   <address-setting name="jms.queue.BackEndDelivery" dead-letter-address="jms.queue.BackEndDeliveryUndelivery" expiry-address="jms.queue.ExpiryQueue" redelivery-delay="10000" max-delivery-attempts="5"/>
   <address-setting name="jms.queue.FrontEndDelivery" dead-letter-address="jms.queue.FrontEndDeliveryUndelivery" expiry-address="jms.queue.ExpiryQueue" redelivery-delay="10000" max-delivery-attempts="5"/>
   ...
   <jms-queue name="ExpiryQueue" entries="java:/jms/queue/ExpiryQueue"/>
   <jms-queue name="DLQ" entries="java:/jms/queue/DLQ"/>
   <jms-queue name="BackEndDelivery" entries="java:jboss/exported/jms/queue/BackEndDelivery"/>
   <jms-queue name="FrontEndDelivery" entries="java:jboss/exported/jms/queue/FrontEndDelivery"/>
   <jms-queue name="BackEndDeliveryUndelivery" entries="java:jboss/exported/jms/queue/BackEndDeliveryUndelivery"/>
   <jms-queue name="FrontEndDeliveryUndelivery" entries="java:jboss/exported/jms/queue/FrontEndDeliveryUndelivery"/>
   ...
</subsystem>

Java EJB 3.0 MDB annotations:

@MessageDriven(activationConfig = {
        @ActivationConfigProperty(propertyName = "destination", propertyValue = "BackEndDelivery"),
        @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
        @ActivationConfigProperty(propertyName = "messageSelector", propertyValue = "Action='BackEndEntryPoint'") }, mappedName = "BackEndDelivery")
@TransactionManagement(TransactionManagementType.BEAN)

Solution

  • What you're seeing is the expected behavior. If there is a message which doesn't match the selector of any of the queue's consumers then the message won't be consumed. It would only be sent to the DLQ if a client attempted to consume the message and failed 5 times (i.e. the value you've set for max-delivery-attempts). It would only be sent to the ExpiryQueue if the message had an expiration time (which apparently it doesn't).

    You can force the message to have an expiration time by setting the expiry-delay address setting, e.g.:

    <address-setting name="jms.queue.BackEndDelivery" dead-letter-address="jms.queue.BackEndDeliveryUndelivery" expiry-address="jms.queue.ExpiryQueue" expiry-delay="5000" redelivery-delay="10000" max-delivery-attempts="5"/>
    <address-setting name="jms.queue.FrontEndDelivery" dead-letter-address="jms.queue.FrontEndDeliveryUndelivery" expiry-address="jms.queue.ExpiryQueue" expiry-delay="5000" redelivery-delay="10000" max-delivery-attempts="5"/>
    

    By setting expiry-delay="5000" you force any message that is not consumed within 5 seconds to be sent to the ExpiryQueue.