8 Replies Latest reply on Nov 2, 2006 5:30 AM by Andrey Tol

    Own dead letter queue

    Andrey Tol Newbie

      I want to write erroneous messages in own dead letter queue (sns/DLQ).
      For this purpose I use the following code:

      ejb-jar.xml:

      <ejb-jar>
       <description>HearerMDB</description>
       <display-name>HearerMDB</display-name>
       <enterprise-beans>
       <message-driven>
       <ejb-name>HearerMDB</ejb-name>
       <ejb-class>com.hearer.Hearer</ejb-class>
       <message-destination-type>javax.jms.Queue</message-destination-type>
       <activation-config>
       <activation-config-property>
       <activation-config-property-name>MaxPoolSize</activation-config-property-name>
       <activation-config-property-value>6</activation-config-property-value>
       </activation-config-property>
       <activation-config-property>
       <activation-config-property-name>providerAdapterJNDI</activation-config-property-name>
       <activation-config-property-value>java:/SnsJMSProvider</activation-config-property-value>
       </activation-config-property>
       </activation-config>
       </message-driven>
       </enterprise-beans>
      </ejb-jar>
      


      jboss.xml
      <jboss>
       <enterprise-beans>
       <message-driven>
       <ejb-name>HearerMDB</ejb-name>
       <destination-jndi-name>queue/interlayC</destination-jndi-name>
       <configuration-name>Standard2 Message Driven Bean</configuration-name>
       <invoker-bindings>
       <invoker>
       <invoker-proxy-binding-name>sintel-message-driven-bean</invoker-proxy-binding-name>
       </invoker>
       </invoker-bindings>
       </message-driven>
       </enterprise-beans>
      
       <invoker-proxy-bindings>
       <invoker-proxy-binding>
       <name>sintel-message-driven-bean</name>
       <invoker-mbean>sintel</invoker-mbean>
       <proxy-factory>org.jboss.ejb.plugins.jms.JMSContainerInvoker</proxy-factory>
       <proxy-factory-config>
       <JMSProviderAdapterJNDI>java:/SnsJMSProvider</JMSProviderAdapterJNDI>
       <ServerSessionPoolFactoryJNDI>StdJMSPool</ServerSessionPoolFactoryJNDI>
       <CreateJBossMQDestination>false</CreateJBossMQDestination>
       <MinimumSize>1</MinimumSize>
       <MaximumSize>15</MaximumSize>
       <KeepAliveMillis>30000</KeepAliveMillis>
       <MaxMessages>1</MaxMessages>
       <MDBConfig>
       <ReconnectIntervalSec>10</ReconnectIntervalSec>
       <DLQConfig>
       <DestinationQueue>queue/sns/DLQ</DestinationQueue>
       <MaxTimesRedelivered>10</MaxTimesRedelivered>
       <TimeToLive>0</TimeToLive>
       </DLQConfig>
       </MDBConfig>
       </proxy-factory-config>
       </invoker-proxy-binding>
       </invoker-proxy-bindings>
      
       <container-configurations>
       <container-configuration>
       <container-name>Standard2 Message Driven Bean</container-name>
       <call-logging>true</call-logging>
       <invoker-proxy-binding-name>sintel-message-driven-bean</invoker-proxy-binding-name>
       <container-interceptors>
       <interceptor>org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor</interceptor>
       <interceptor>org.jboss.ejb.plugins.LogInterceptor</interceptor>
       <interceptor>org.jboss.ejb.plugins.RunAsSecurityInterceptor</interceptor>
       <!-- CMT -->
       <interceptor transaction="Container">org.jboss.ejb.plugins.TxInterceptorCMT</interceptor>
       <interceptor transaction="Container">org.jboss.ejb.plugins.CallValidationInterceptor</interceptor>
       <interceptor transaction="Container">org.jboss.ejb.plugins.MessageDrivenInstanceInterceptor</interceptor>
       <!-- BMT -->
       <interceptor transaction="Bean">org.jboss.ejb.plugins.MessageDrivenInstanceInterceptor</interceptor>
       <interceptor transaction="Bean">org.jboss.ejb.plugins.MessageDrivenTxInterceptorBMT</interceptor>
       <interceptor transaction="Bean">org.jboss.ejb.plugins.CallValidationInterceptor</interceptor>
       <interceptor>org.jboss.resource.connectionmanager.CachedConnectionInterceptor</interceptor>
       </container-interceptors>
       <instance-pool>org.jboss.ejb.plugins.MessageDrivenInstancePool</instance-pool>
       <instance-cache></instance-cache>
       <persistence-manager></persistence-manager>
       <container-pool-conf>
       <MaximumSize>100</MaximumSize>
       </container-pool-conf>
       </container-configuration>
       </container-configurations>
      </jboss>
      


      But messages are still kept in standard queue (queue/DLQ).
      What is made incorrectly?

        • 1. Re: Own dead letter queue
          jaikiran pai Master

          Not quite clear about your requirement. Do you want the messages which are discarded from your "queue/interlayC" to be sent to "queue/sns/DLQ" ?
          If thats what you want then, you need not do all this. Just add an entry to the "queue/interlayC" configuration as follows:

          <mbean code="org.jboss.mq.server.jmx.Queue"
           name="jboss.mq.destination:service=Queue,name=interlayC">
           <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
          
          .......
          
           <!--Jaikiran: Configuring to use my own DLQ on expiration of message -->
           <depends optional-attribute-name="ExpiryDestination">jboss.mq.destination:service=Queue,name=sns/DLQ</depends>
          
          .......
           </mbean>


          For more details have a look at:

          http://wiki.jboss.org/wiki/Wiki.jsp?page=ExpiryDestination



          • 2. Re: Own dead letter queue
            Andrey Tol Newbie

             

            "jaikiran" wrote:
            Not quite clear about your requirement. Do you want the messages which are discarded from your "queue/interlayC" to be sent to "queue/sns/DLQ" ?


            Yes. I want the messages that could not be processed due to some failure in the system from "queue/interlayC" to be sent to "queue/sns/DLQ".

            "jaikiran" wrote:
            If thats what you want then, you need not do all this. Just add an entry to the "queue/interlayC" configuration as follows:

            <mbean code="org.jboss.mq.server.jmx.Queue"
             name="jboss.mq.destination:service=Queue,name=interlayC">
             <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
            
            .......
            
             <!--Jaikiran: Configuring to use my own DLQ on expiration of message -->
             <depends optional-attribute-name="ExpiryDestination">jboss.mq.destination:service=Queue,name=sns/DLQ</depends>
            
            .......
             </mbean>


            For more details have a look at:

            http://wiki.jboss.org/wiki/Wiki.jsp?page=ExpiryDestination



            From Wiki:
            DLQ: A dead letter queue stores requests that could not be processed due to some failure in the system, application or configuration.
            ExpiryDestination: expired messages can now be moved into a separate destination

            In my opinion, it is different queues. I have tried yours the decision. It has not worked.
            Thanks.

            • 3. Re: Own dead letter queue
              jaikiran pai Master

               

              Yes. I want the messages that could not be processed due to some failure in the system from "queue/interlayC" to be sent to "queue/sns/DLQ"


              In your onMessage method of the MDB, which is listening on queue/interlayC, are you invoking messageDrivenContext.setRollbackOnly(). Only when you invoke that method, the message will be sent to the DLQ(after trying to redeliver it for "redeliveryLimit" number of times).

              I do remember trying exactly the same usecase that you are working on, and it had worked for me. BTW, which version of JBoss are you using?

              • 4. Re: Own dead letter queue
                Andrey Tol Newbie

                 

                "jaikiran" wrote:

                In your onMessage method of the MDB, which is listening on queue/interlayC, are you invoking messageDrivenContext.setRollbackOnly(). Only when you invoke that method, the message will be sent to the DLQ(after trying to redeliver it for "redeliveryLimit" number of times).

                My messages after "redeliveryLimit" attempts are sent in "queue/DLQ", instead of in "queue/sns/DLQ".

                My MDB:
                public class Hearer implements MessageListener
                {
                 public void onMessage(Message recvMsg)
                 {
                 ....
                 }
                }
                



                I do remember trying exactly the same usecase that you are working on, and it had worked for me. BTW, which version of JBoss are you using?

                JBOSS 4.0.4 GA

                • 5. Re: Own dead letter queue
                  jaikiran pai Master

                   

                  From Wiki:
                  DLQ : A dead letter queue stores requests that could not be processed due to some failure in the system, application or configuration.
                  ExpiryDestination : expired messages can now be moved into a separate destination

                  In my opinion, it is different queues.


                  Yes, you are right. Sorry my bad.


                  • 6. Re: Own dead letter queue
                    Andrey Tol Newbie

                     

                    "jaikiran" wrote:
                    Yes, you are right. Sorry my bad.


                    Ok. But why messages are located in "queue/DLQ", instead of in "queue/sns/DLQ"? :(

                    • 7. Re: Own dead letter queue
                      jaikiran pai Master

                      You mention that your ejb-jar.xml contains:

                      <ejb-jar>
                       <description>HearerMDB</description>
                       <display-name>HearerMDB</display-name>
                       <enterprise-beans>
                       <message-driven>
                       <ejb-name>HearerMDB</ejb-name>
                       <ejb-class>com.hearer.Hearer</ejb-class>
                       <message-destination-type>javax.jms.Queue</message-destination-type>
                       <activation-config>
                       <activation-config-property>
                       <activation-config-property-name>MaxPoolSize</activation-config-property-name>
                       <activation-config-property-value>6</activation-config-property-value>
                       </activation-config-property>
                       <activation-config-property>
                       <activation-config-property-name>providerAdapterJNDI</activation-config-property-name>
                       <activation-config-property-value>java:/SnsJMSProvider</activation-config-property-value>
                       </activation-config-property>
                       </activation-config>
                       </message-driven>
                       </enterprise-beans>
                      </ejb-jar>


                      But the contents that you have specified are not part of the ejb-jar dtd (http://java.sun.com/dtd/ejb-jar_2_0.dtd). Any reference from where you used these contents



                      • 8. Re: Own dead letter queue
                        Andrey Tol Newbie

                         

                        "jaikiran" wrote:
                        You mention that your ejb-jar.xml contains:
                        But the contents that you have specified are not part of the ejb-jar dtd (http://java.sun.com/dtd/ejb-jar_2_0.dtd). Any reference from where you used these contents


                        I used
                        <ejb-jar version="3.0"
                         xmlns="http://java.sun.com/xml/ns/javaee"
                         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                         http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd">