3 Replies Latest reply on Oct 9, 2014 5:11 AM by azureel

    Message Driven Bean & Queue name (Destination)

    maxant

      I want to create a message driven bean that listens to the default "test" queue. I am using the standalone-full.xml configuration with JBoss 7.1.1.Final.

       

      In the config, the queue is defined as:

       

          <jms-queue name="testQueue">

              <entry name="queue/test"/>

              <entry name="java:jboss/exported/jms/queue/test"/>

          </jms-queue>

       

      I define my bean as:

       

      @MessageDriven(

              //name="java:/queue/test" - doesnt seem to help

              //mappedName="java:/queue/test" - doesnt seem to help either

              activationConfig={@ActivationConfigProperty(propertyName="destination", propertyValue="java:/queue/test")}

              )

      public class MailService implements MessageListener {   

          public void onMessage(Message m) {

              ...

          }  

      }

       

      I was expecting to use "name" or "mappedName" in the @MessageDriven annotation, but instead, it seems as though I have to use the ActivationConfigProperty.

       

      This doesn't seem very portable.  If I deploy the same bean in Glassfish, I have to use "name" or "mappedName". 

       

      So is that a bug in JBoss or Glassfish? Reading chapter 5 of the EJB 3.1 spec, it doesn't seem to go into that much detail, which is a shame.

       

      If I leave out the activation configuration, JBoss doesn't deploy the bean, stating that the "destination" is mandatory.

       

      Thanks,

      Ant

        • 1. Re: Message Driven Bean & Queue name (Destination)
          jmesnil

          Reading the MessageDriven annotation javadoc, http://docs.oracle.com/javaee/6/api/javax/ejb/MessageDriven.html, I think JBoss implemenation is correct.

           

          "name" is the ejb-name of the bean, it makes no sense to use it for the queue name.

          "mappedName" is not portable:

           

               Application servers are not required to support any particular form or type of mapped name, nor the ability to use mapped names. The mapped name is product-dependent and often installation-dependent. No use of a mapped name is portable.

           

          On the other hand, using a destination @ActivationConfigProperty *is* portable.

           

          hope that helps,

          jeff

          • 2. Re: Message Driven Bean & Queue name (Destination)
            garcimouche

            ActivationConfigProperty is portable but the 'destination' property name isn't.....So is there a way to write a portable MDB in EE6?

            • 3. Re: Re: Message Driven Bean & Queue name (Destination)
              azureel

              Hello,

               

              It's been 2 years but I recently had the same problem, so I want to share my solution to this problem: Don't use slash character in your destination.

               

              "Physical Destination Name" (which corresponds to "destination" property of the JMS Queue) MAY contain slash ("/") character according to JMS specification (JSR: 343). JBoss supports this character, but in the GlassFish implementation that field has more restrictions (cannot start with number, cannot contain non-alpha-numeric chars etc.). So, in terms of compatibility, it is best to choose your queue (resource) names with the only allowed characters in specification:

               

              Subscription name characters and length

              The JMS provider must allow a durable or non-durable subscription name to contain the following characters:

              * Java letters

              * Java digits

              * Underscore ( _ )

              * Dot ( . )

              * Minus ( - )

              JMS providers may support additional characters to these, but applications which use them may not be portable.

              The JMS provider must allow a durable or non-durable subscription name to have up to 128 characters.

              JMS providers may support names longer than this, but applications which use longer names may not be portable.

               

              Source: https://jcp.org/en/jsr/detail?id=343

               

               

              So this is my working configuration for domain.xml (GlassFish),

               

              <domain log-root="${com.sun.aas.instanceRoot}/logs" application-root="${com.sun.aas.instanceRoot}/applications" version="89">
                  <!-- ... -->
                  <resources>
                <!-- ... -->
                      <admin-object-resource res-adapter="jmsra" res-type="javax.jms.Queue" description="mychosenqueue" jndi-name="mychosenqueue">
                          <property name="Name" value="mychosenqueue"></property>
                      </admin-object-resource>
                </resources>
                <servers>
                      <server name="server" config-ref="server-config">
                          <!-- ... -->
                          <resource-ref ref="mychosenqueue"></resource-ref>
                      </server>
                  </servers>
              </domain>
              

               

               

              Corresponding queue configuration for standalone-full.xml (JBoss & WildFly)

               

              <server xmlns="urn:jboss:domain:2.1">
                  <!-- ... -->
                  <profile>
                      <!-- ... -->
                      <subsystem xmlns="urn:jboss:domain:messaging:2.0">
                          <hornetq-server>
                              <!-- ... -->
                              <jms-destinations>
                                  <!-- ... -->
                                  <jms-queue name="mychosenqueue">
                                      <entry name="java:/mychosenqueue"/>
                                      <durable>true</durable>
                                  </jms-queue>
                              </jms-destinations>
                          </hornetq-server>
                      </subsystem>
                  </profile>
              </server>
              

               

               

              And the MessageDrivenBean code;

               

              package com.cagricelebi.datagw.ejb;
              
              
              import com.cagricelebi.datagw.lib.log.Logger;
              import javax.ejb.ActivationConfigProperty;
              import javax.ejb.MessageDriven;
              import javax.inject.Inject;
              import javax.jms.Message;
              import javax.jms.MessageListener;
              import javax.jms.TextMessage;
              
              
              @MessageDriven(
                      //name = "MyQueueProcessorEJB",
                      mappedName = "mychosenqueue", // glassfish uses this.
                      activationConfig = {
                          @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
                          @ActivationConfigProperty(propertyName = "destination", propertyValue = "mychosenqueue"), // jboss | wildfly uses this.
                          @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
                      }
              )
              public class MyQueueProcessorBean implements MessageListener {
                  @Inject
                  Logger logger;
                  @Override
                  public void onMessage(Message message) {
                      try {
                          String body = ((TextMessage) message).getText();
                          logger.log("(onMessage) Body: " + body);
                      } catch (Exception e) {
                          logger.log(e);
                      }
                  }
              }
              

               

              Hope this helps.