4 Replies Latest reply on Aug 27, 2014 6:23 AM by chschroe

    Use of jms-destination element in deployment descriptor

    chschroe

      Hi all!

      I am struggling with the "jms-destination" element in the deployment descriptor (ejb-jar.xml). My understanding (probably wrong ...) was that I could use this element to declare a JMS destination to be used in a session bean.

      The following works:

       

      <!-- excerpt from ejb-jar.xml -->
          <enterprise-beans>
              <session>
                  <ejb-name>TestBean1</ejb-name>
                  <jms-destination>
                      <name>jms/test1</name>
                      <interface-name>javax.jms.Topic</interface-name>
                      <destination-name>test</destination-name>
                  </jms-destination>
              </session>
          </enterprise-beans>
      

       

      @Singleton
      public class TestBean1 {
          @Resource(lookup = "jms/test1")
          private Destination destination;
      
          @Inject
         private JMSContext context;
      
          ...
      }
      

       

      I can use the JMS context together with the destination object to send messages.

      However, when I create a second enterprise application with a similar declaration in the ejb-jar.xml, an error occurs upon deployment:

       

      <!-- excerpt from ejb-jar.xml -->
          <enterprise-beans>
              <session>
                  <ejb-name>TestBean2</ejb-name>
                  <jms-destination>
                      <name>jms/test2</name>
                      <interface-name>javax.jms.Topic</interface-name>
                      <destination-name>test</destination-name>
                  </jms-destination>
              </session>
         </enterprise-beans>
      

       

      org.jboss.msc.service.DuplicateServiceException: Service jboss.messaging.default.jms.topic.test is already registered
      

      It seems that the destination names must be different. But why would it be disallowed to create two enterprise applications that use the same JMS topic? I guess that my usage of the "jms-destination" element is wrong, but since I was unable to find any documentation (this element is not even mentioned in the EJB spec), I have no idea what I should do instead.

      Can anybody explain?

       

      Thank a lot,

      Christian

        • 1. Re: Use of jms-destination element in deployment descriptor
          jmesnil

          The name of the destination (specified by <destination-name>) is global to the application server.

          The topics can be look up only by their respective applications but underneath, all the topics are managed by a single HornetQ server. The name of the topics must be unique to be properly identified by HornetQ.

           

          Note that this <destination-name> element is optional and if you don't specify it, a unique name is built (using the application/module/component names + the destination<name> element).

          • 2. Re: Use of jms-destination element in deployment descriptor
            chschroe

            Thanks for your answer.

            It seems that I misunderstood the meaning of the "jms-destination" element. I thought I could use it to define in the deployment descriptor the name of the topic or queue to which the messages will be sent by the application. If I want two separate applications to communicate via a shared queue, how can I make sure both actually use the same? If I omit the "destiation-name" then both applications will create their own destinations, which is not what I need.

            In my case the situation is even worse because I do not use the embedded HornetQ broker, but an external ActiveMQ which is connected via an appropriate resource adapter. The enterprise application (inside WildFly) should communicate with an external application using JMS, so it is crucial that the topic name is well defined.

            Is there any best practice how to solve this?

             

            PS: Where can I find a specification for the "jms-destination" element?

            • 3. Re: Use of jms-destination element in deployment descriptor
              jmesnil

              The jms-destination element is specified in the Java EE7 specification (https://jcp.org/aboutJava/communityprocess/final/jsr342/index.html)

               

              If you want to use a global queue that is shared between 2 applications, I'd advise to create the queue directly in ActiveMQ without using the Java EE7 destination definitions.

               

              Alternatively, you could define the queue in one application in the java:global/ namespace. It will then be available for the other applications (that all have access to the java:global/ namespace).

              However if you ever undeploy the application that defines the queue, the JNDI entry will be removed and no application will be able to look it up.

              1 of 1 people found this helpful
              • 4. Re: Use of jms-destination element in deployment descriptor
                chschroe

                Thanks for the link!

                So the jms-destination element does actually define a destination and is not used (as I thought) to reference an existing destination. Is this correct?

                When I create the queue in ActiveMQ, how do I tell the application which queue should be used? Or should I administratively add a global JNDI entry that references that destination and reference this JNDI entry in the deployment descriptor using "resource-env-ref" or "message-destination-ref" elements?