12 Replies Latest reply on Apr 18, 2013 11:42 AM by puttime

    ActiveMQ Integration

      I posted the following on the ActiveMQ forum

      ----------

      I am trying to create an MDB in jboss that runs off an ActiveMQ queue.

      To do this, you apparently need add something like the following into the jms-ds.xml file, then you can say in your mdb what provider to use.

       <!-- The ActiveMQ JMS provider loader -->
       <mbean code="org.jboss.jms.jndi.JMSProviderLoader"
       name="jboss.mq:service=JMSProviderLoader,name=ActiveMQJMSProvider">
       <attribute name="ProviderName">ActiveMQJMSProvider</attribute>
       <attribute name="ProviderAdapterClass">
       org.jboss.jms.jndi.JNDIProviderAdapter
       </attribute>
       <!-- The combined connection factory -->
       <attribute name="FactoryRef">java:/activemq/QueueConnectionFactory</attribute>
      
       <!-- The queue connection factory -->
       <attribute name="QueueFactoryRef">java:/activemq/QueueConnectionFactory</attribute>
      
       <!-- The topic factory -->
       <attribute name="TopicFactoryRef">java:/activemq/QueueConnectionFactory</attribute>
      
       <!-- Uncomment to use HAJNDI to access JMS
       <attribute name="Properties">
       java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
       java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
       java.naming.provider.url=localhost:1100
       </attribute>
       -->
       </mbean>


      So my mdb is annotated with the following.
      @MessageDriven(activationConfig =
      {
       @ActivationConfigProperty(propertyName="destinationType",
       propertyValue="javax.jms.Queue"),
       @ActivationConfigProperty(propertyName="destination",
       propertyValue="activemq/queue/SecurityChanged"),
       @ActivationConfigProperty(propertyName="connectionFactoryName",
       propertyValue="activemq/QueueConnectionFactory"),
       @ActivationConfigProperty(propertyName="resourceAdaptorName",
       propertyValue="activemq-ra-4.0.rar"),
       @ActivationConfigProperty(propertyName="providerAdapterJNDI",
       propertyValue="java:/ActiveMQJMSProvider")
      })


      I get the following exception when running I run my jboss server.

      javax.jms.JMSException: Not Supported.
       at org.apache.activemq.ra.ManagedConnectionProxy.createConnectionConsumer(ManagedConnectionProxy.java:221)
       at org.jboss.ejb3.mdb.MDB.innerCreateQueue(MDB.java:530)
       at org.jboss.ejb3.mdb.MDB.innerCreate(MDB.java:454)
       at org.jboss.ejb3.mdb.MDB.innerStart(MDB.java:267)
       at org.jboss.ejb3.mdb.MDB.start(MDB.java:256)
      

      Is there a differenct connection factory i should be using that supports the createConnectionConsumer method? I just have the standard of what comes in the activemq-4.0-ra.xml.


      -------------------------

      And someone on the ActiveMQ forum replied with the following

      It seems that with that configuration the JCA activation spec stuff is
      not being used to deliver messages to JBoss. JBoss is trying to do
      the message delivery itself by setting up a connectionConsumer. I
      would cross post this question to the JBoss mailing lists to find out
      why JBoss is trying to create connection consumer if you've configured
      the activation spec properties.

      -----------------------------

      Any help would be appreciated. I am just trying to get an MDB configured to work off an ActiveMQ queue.

      Thanks

      --Bo

        • 1. Re: ActiveMQ Integration
          jnerd

          Hi all,

          I am facing the same problem with JBoss 4.0.4GA, EJB3.0 option and activeMQ 4.0.1

          My configuratioin is quite similar and I am running into the same JMSException. The stack trace is looking a bit differetn though:

          javax.jms.JMSException: Not Supported.
           at org.apache.activemq.ra.ManagedConnectionProxy.createConnectionConsumer(ManagedConnectionProxy.java:221)
           at org.jboss.ejb3.mdb.MDB.innerCreateQueue(MDB.java:424)
           at org.jboss.ejb3.mdb.MDB.innerCreate(MDB.java:347)
           at org.jboss.ejb3.mdb.MDB.innerStart(MDB.java:225)
           at org.jboss.ejb3.mdb.MDB.start(MDB.java:214)
          
          and later
          
          javax.jms.JMSException: Not Supported.
           at org.apache.activemq.ra.ManagedConnectionProxy.createConnectionConsumer(ManagedConnectionProxy.java:221)
           at org.jboss.ejb3.mdb.MDB.innerCreateQueue(MDB.java:424)
           at org.jboss.ejb3.mdb.MDB.innerCreate(MDB.java:347)
           at org.jboss.ejb3.mdb.MDB.innerStart(MDB.java:225)
           at org.jboss.ejb3.mdb.MDB$ExceptionListenerImpl.onException(MDB.java:1133)
           at org.jboss.ejb3.mdb.MDB$1.run(MDB.java:237)
          


          The method called (createConnectionConsumer()) is an optional operation. Why does JBoss depend on it?

          Having a look at the JBoss EJB3 code a FIXME statement is really distracting (org.jboss.ejb3.mdb.MDB.java: line 405 ff):

           // FIXME: This is not portable, only works for JBossMQ
           if (queue == null)
           queue = (Queue) createDestination(Queue.class,
           context,
           "queue/" + jndiSuffix,
           jndiSuffix);
          
          
           if (queue != null)
           {
           // set up the server session pool
           serverSessionPool = createSessionPool(queue,
           qConnection,
           true, // tx
           acknowledgeMode.ordinal(),
           new MessageListenerImpl(this));
           log.debug("Server session pool: " + pool);
          
           // create the connection consumer
           connectionConsumer =
           qConnection.createConnectionConsumer(queue,
           config.getMessageSelector(),
           serverSessionPool,
           config.getMaxMessages());
           log.debug("Connection consumer: " + connectionConsumer);
           }
          


          Any ideas or comments on this?

          Greetings and Thanks,

          Patrick

          • 2. Re: ActiveMQ Integration
            jnerd

            Autch! I looked a bit closer to the EJB3 MDB code and found out, that we will probably have no chance changing the JMS implementation used.

            The code is totally dependent on JBossMQ. For example method MDB.createDestination() (line 621 ff) looks like this:

             /**
             * Create and or lookup a JMS destination.
             *
             * @param type Either javax.jms.Queue or javax.jms.Topic.
             * @param ctx The naming context to lookup destinations from.
             * @param jndiName The name to use when looking up destinations.
             * @param jndiSuffix The name to use when creating destinations.
             * @return The destination.
             * @throws IllegalArgumentException Type is not Queue or Topic.
             * @throws Exception Description of Exception
             */
             protected Destination createDestination(final Class type,
             final Context ctx,
             final String jndiName,
             final String jndiSuffix)
             throws Exception
             {
             try
             {
             // first try to look it up
             return (Destination) ctx.lookup(jndiName);
             }
             catch (NamingException e)
             {
             // is JMS?
             if (getDestination() == null)
             {
             return null;
             }
             else
             {
             // if the lookup failes, the try to create it
             log.warn("destination not found: " + jndiName + " reason: " + e);
             log.warn("creating a new temporary destination: " + jndiName);
            
             //
             // jason: we should do away with this...
             //
             // attempt to create the destination (note, this is very
             // very, very unportable).
             //
            
             MBeanServer server = org.jboss.mx.util.MBeanServerLocator.locateJBoss();
            
             String methodName;
             if (type == Topic.class)
             {
             methodName = "createTopic";
             }
             else if (type == Queue.class)
             {
             methodName = "createQueue";
             }
             else
             {
             // type was not a Topic or Queue, bad user
             throw new IllegalArgumentException
             ("Expected javax.jms.Queue or javax.jms.Topic: " + type);
             }
            
             // invoke the server to create the destination
             server.invoke(new ObjectName("jboss.mq:service=DestinationManager"),
             methodName,
             new Object[]{jndiSuffix},
             new String[]{"java.lang.String"});
            
             // try to look it up again
             return (Destination) ctx.lookup(jndiName);
             }
             }
             }
            


            So what we have here are direct references to JBossMQ (org.jboss.mx.util.MBeanServerLocator) and hardcoded JMX lookups that are (as far as I think) not mandatory (jboss.mq:service=DestinationManager).

            Did I miss something in the documentation that says that EJB3 only works with JBossMQ?

            Any feedback appreciated.
            Greetings and thanks,

            Patrick

            • 3. Re: ActiveMQ Integration
              alesj

              If it is dependent on jmx it doesn't mean it is dependent on JBossMQ.
              Like all services in JBossAS, JMS is also registered in MBeanServer - and that's why it looks there to find Destination.

              Ok, these are my first thoughts - haven't really digged into JBoss MDB + JMS.

              • 4. Re: ActiveMQ Integration
                jnerd

                Hi alesj,

                Yes, you are totally right. Sorry. I mixed up org.jboss.mx and org.jboss.jms packages.

                But still the "jboss.mq:service=DestinationManager" is a JBossMQ thing, isn't it? And the original question remains: Is it still possible to exchange the JMS implementation if you are using the EJB3 container?

                Cheers,

                Patrick

                • 5. Re: ActiveMQ Integration
                  bdecoste

                  For what it's worth, we are currently refactoring all of the MDB and Consumer code to be exclusively RAR based and to remove the dependency on the MBean server so that we have all of the capabilitites (e.g. ability to create temporary queues) in E-EJB3. So this issue is on the radar screen.

                  • 6. Re: ActiveMQ Integration

                    Has anyone successfully deployed an mdb to consume an ActiveMQ queue on jboss 4.0.4? If not and this is just on the radar, is there any timeframe for it? is there a jira issue i can watch?

                    • 7. Re: ActiveMQ Integration
                      bdecoste

                      Here is the JIRA task:

                      http://jira.jboss.com/jira/browse/EJBTHREE-389

                      You should be able to use ActiveMQ, but you cannot currently create temporary queues. If you create the queue beforehand on ActiveMQ, then deploy the destination to JBoss, you should be fine. The problem only exists when we try to create a non-JBossMQ temporary queue.

                      We are targeting all of the MDB refactoring to be completed by our next release to coincide with the release of the JBoss 5 beta - mid to late July.

                      • 8. Re: ActiveMQ Integration
                        jnerd
                        • 9. Re: ActiveMQ Integration
                          jc7442

                          Even when queue is already created, MDB can not be deploy. Problem in the first post was due to createConnectionConsumer wich looks like an optional method.

                          Even if queue are already deployed, MDB+ActiveMQ does not works !

                          • 10. Re: ActiveMQ Integration
                            redijedi

                            I'm experiencing the same problem. Has anyone resolved this?

                            • 11. Re: ActiveMQ Integration
                              fabiowillow

                              I'm facing the same problem.

                              I'm using ActiveMQ+JBoss4.0.4.GA also.

                              I CAN produce messages using tcp.
                              I CAN consume those messages.

                              I CAN produce messages using jndi (through a servlet call i.e.)
                              I CAN consume those messages.

                              I CAN deploy a MDB succesfully (that means no console errors).
                              BUT the MDB never consumes those messages.

                              Does any one experienced this problem? Everything seems to be fine.
                              If i change the configuration to run with JBossMQ it works fine.
                              I've read every single page and i simply don't know what else to do.




                              • 12. Re: ActiveMQ Integration
                                puttime

                                Was there any conclusion to this?

                                Was the integration successful?

                                 

                                Cause I'm trying to do it using SY 0.8, and still have not figured out how to do it.