14 Replies Latest reply on May 3, 2012 4:37 PM by jbertram

    MDB Quickstart Example Question

    foutjo

      Currently have the following sample message bean deployed on a as-7 server.

      Used standalone-full.xml to start the server and the messages on the server console seem to indicate that the message bean and HornetQ started successfully.

       

      Console Log:

       

      06:00:04,868 INFO  [org.hornetq.core.server.impl.FileLockNodeManager] (MSC service thread 1-4) Waiting to obtain live lock

      06:00:04,869 INFO  [org.hornetq.core.server.impl.FileLockNodeManager] (MSC service thread 1-4) Live Server Obtained live lock

      06:00:05,129 INFO  [org.hornetq.core.remoting.impl.netty.NettyAcceptor] (MSC service thread 1-4) Started Netty Acceptor version 3.2.5.Final-a96d88c lidplin12:5445 for CORE protocol

      06:00:05,131 INFO  [org.hornetq.core.remoting.impl.netty.NettyAcceptor] (MSC service thread 1-4) Started Netty Acceptor version 3.2.5.Final-a96d88c lidplin12:5455 for CORE protocol

      06:00:05,133 INFO  [org.hornetq.core.server.impl.HornetQServerImpl] (MSC service thread 1-4) Server is now live

      06:00:05,133 INFO  [org.hornetq.core.server.impl.HornetQServerImpl] (MSC service thread 1-4) HornetQ Server version 2.2.11.Final (HQ_2_2_11_FINAL_AS7, 122) [e7a706f2-5cd8-11e1-9420-e06995db4b43]) started

      06:00:05,136 INFO  [org.hornetq.core.server.impl.HornetQServerImpl] (MSC service thread 1-6) trying to deploy queue jms.queue.testQueue

      06:00:05,142 INFO  [org.jboss.as.messaging] (MSC service thread 1-6) JBAS011601: Bound messaging object to jndi name java:/queue/test

      06:00:05,143 INFO  [org.jboss.as.messaging] (MSC service thread 1-6) JBAS011601: Bound messaging object to jndi name java:jboss/exported/jms/queue/test

      06:00:05,155 INFO  [org.jboss.as.messaging] (MSC service thread 1-5) JBAS011601: Bound messaging object to jndi name java:/ConnectionFactory

      06:00:05,156 INFO  [org.hornetq.core.server.impl.HornetQServerImpl] (MSC service thread 1-8) trying to deploy queue jms.topic.testTopic

      06:00:05,174 INFO  [org.jboss.as.messaging] (MSC service thread 1-8) JBAS011601: Bound messaging object to jndi name java:/topic/test

      06:00:05,175 INFO  [org.jboss.as.messaging] (MSC service thread 1-8) JBAS011601: Bound messaging object to jndi name java:jboss/exported/jms/topic/test

      06:00:05,176 INFO  [org.jboss.as.messaging] (MSC service thread 1-2) JBAS011601: Bound messaging object to jndi name java:jboss/exported/jms/RemoteConnectionFactory

      06:00:05,177 INFO  [org.jboss.as.deployment.connector] (MSC service thread 1-3) JBAS010406: Registered connection factory java:/JmsXA

      06:00:05,177 INFO  [org.jboss.as.messaging] (MSC service thread 1-2) JBAS011601: Bound messaging object to jndi name java:/RemoteConnectionFactory

      06:00:05,184 INFO  [org.hornetq.ra.HornetQResourceAdapter] (MSC service thread 1-3) HornetQ resource adaptor started

      06:00:05,185 INFO  [org.jboss.as.connector.services.ResourceAdapterActivatorService$ResourceAdapterActivator] (MSC service thread 1-3) IJ020002: Deployed: file://RaActivatorhornetq-ra

      06:00:05,187 INFO  [org.jboss.as.deployment.connector] (MSC service thread 1-8) JBAS010401: Bound JCA ConnectionFactory [java:/JmsXA]

      06:00:05,203 INFO  [org.jboss.as] (Controller Boot Thread) JBAS015874: JBoss AS 7.1.0.Final "Thunder" started in 2007ms - Started 172 of 249 services (75 services are passive or on-demand)

      06:00:05,209 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-3) JBAS015876: Starting deployment of "LIDP-ADMI2.jar"

      06:00:05,976 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-7) JNDI bindings for session bean named TestBean2 in deployment unit deployment "LIDP-ADMI2.jar" are as follows:

       

          java:global/LIDP-ADMI2/TestBean2!com.lidp.main.TestBeanRemoteInf

          java:app/LIDP-ADMI2/TestBean2!com.lidp.main.TestBeanRemoteInf

          java:module/TestBean2!com.lidp.main.TestBeanRemoteInf

          java:jboss/exported/LIDP-ADMI2/TestBean2!com.lidp.main.TestBeanRemoteInf

          java:global/LIDP-ADMI2/TestBean2

          java:app/LIDP-ADMI2/TestBean2

          java:module/TestBean2

       

      06:00:05,979 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-7) JNDI bindings for session bean named TestBean1 in deployment unit deployment "LIDP-ADMI2.jar" are as follows:

       

          java:global/LIDP-ADMI2/TestBean1!com.lidp.main.TestBeanRemoteInf

          java:app/LIDP-ADMI2/TestBean1!com.lidp.main.TestBeanRemoteInf

          java:module/TestBean1!com.lidp.main.TestBeanRemoteInf

          java:jboss/exported/LIDP-ADMI2/TestBean1!com.lidp.main.TestBeanRemoteInf

          java:global/LIDP-ADMI2/TestBean1

          java:app/LIDP-ADMI2/TestBean1

          java:module/TestBean1

       

      06:00:06,107 INFO  [org.jboss.as.ejb3] (MSC service thread 1-4) JBAS014142: Started message driven bean 'MessageBean' with 'hornetq-ra' resource adapter

      06:00:06,151 INFO  [org.jboss.as.server] (DeploymentScanner-threads - 2) JBAS018559: Deployed "LIDP-ADMI2.jar"

       

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

       

      Message Bean:

       

      @MessageDriven(name = "HelloWorldMDB", activationConfig = {

              @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),

              @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/test"),

              @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge") })

      public class HelloWorldMDB implements MessageListener {

       

          private final static Logger LOGGER = Logger.getLogger(HelloWorldMDB.class

                  .toString());

       

              public void onMessage(Message rcvMessage) {

              TextMessage msg = null;

              try {

                  if (rcvMessage instanceof TextMessage) {

                      msg = (TextMessage) rcvMessage;

                      LOGGER.info("Received Message: " + msg.getText());

                  } else {

                      LOGGER.warning("Message of wrong type: "

                              + rcvMessage.getClass().getName());

                  }

              } catch (JMSException e) {

                  throw new RuntimeException(e);

              }

          }

      }

       

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

       

      The quickstart example includes a servlet client that shows how to write a message to the queue.

       

      Here is the snippet of code it used by the servlet to connect/start/write to the queue:

       

      @Resource(mappedName = "java:/ConnectionFactory")

          private ConnectionFactory connectionFactory;

       

      @Resource(mappedName = "java:/queue/test")

          private Queue queue;

       

      connection = connectionFactory.createConnection();

      Session session = connection.createSession(false,

                   Session.AUTO_ACKNOWLEDGE);

      MessageProducer messageProducer = session.createProducer(queue);

      connection.start();

      TextMessage message = session.createTextMessage();

      message.setText("This is message ");

      messageProducer.send(message);

       

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

       

      My question is how can I write to the queue from java program from within the server application?

      I tried using the same code from above in a simple java class running on the server but I get errors.

       

      Java Client running on server:

       

      class MessageConn

      {

         Connection connection = null;

        

         @Resource(mappedName = "java:/ConnectionFactory")

         private ConnectionFactory connectionFactory;

         @Resource(mappedName = "java:/queue/test")

         private Queue queue;

        

         public MessageConn()

         {

            try

            {

               connection = connectionFactory.createConnection();

               Session session = connection.createSession(false,

                       Session.AUTO_ACKNOWLEDGE);

               MessageProducer messageProducer = session.createProducer(queue);

               connection.start();

              

               TextMessage message = session.createTextMessage();

               for (int i = 0; i < 5; i++) {

                   message.setText("This is message " + (i + 1));

                   messageProducer.send(message);

               }  

       

               System.out.println("Sending message");

               session.close();

            }

            catch (Exception e)

            {

               e.printStackTrace();

            }

         }

      }

       

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

       

      Console Log after java client attempts to connect to queue:

       

      06:00:23,496 ERROR [stderr] (EJB default - 1) java.lang.NullPointerException

      06:00:23,497 ERROR [stderr] (EJB default - 1)     at com.lidp.main.MessageConn.<init>(MessageConn.java:25)

       

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

       

      Should I be using a different method to connect to the queue running from java code from within the server?

       

       

      Any help is greatly appreciated.

       

      Thanks.

        • 1. Re: MDB Quickstart Example Question
          newway

          I have 2 questions:

           

          1. line 24 in your code is?
          2. I'm not an expert in CDI, but in the past those kind of resources where injected correctly only into EJB's - are you sure you can get this data without annotating the class with @Singleton or some other annotation that suites your logic?
          • 2. Re: MDB Quickstart Example Question
            foutjo

            Thanks Noa.

             

             

            24try
              25{
                 26connection = connectionFactory.createConnection();

             

            Not sure what you mean by your second question.

             

            My requirement is a MSB that will process messages from a message queue.

            The messages must be put to the message queue from a SLSB that is also running in the server.

             

            Seems pretty straight forward to me.  My problem is that all of the examples I find for JBoss 7 are

            writing the messages to the message queue from a client outside of the server.

             

            This seems pretty striaght forward and I thought (my first mistake) that this would be easy to get

            working with Jboss 7. 

             

            Do you think that this could be just another instance of JBoss 7 not yet supporting all of the

            variations of MSB's yet?

            • 3. Re: MDB Quickstart Example Question
              jbertram

              What is an "MSB"?

               

              The reason the servlet example works is because you can actually get injection in a servlet.  You can't just inject dependencies in any POJO you want.  Where injection isn't supported you will have to use the traditional JNDI lookup pattern.

              • 4. Re: MDB Quickstart Example Question
                foutjo

                Thanks Justin.

                 

                Sorry I meant MDB - Message Driven Bean

                 

                Would you know of example of the traditional lookup that I would use for this case?

                 

                Also,  will the traditional JNDI stuff work with as-7?  

                 

                Thanks.

                • 5. Re: MDB Quickstart Example Question
                  newway

                  so SLSB will be achived by annotating MessageConn with @Stateless

                  • 6. Re: MDB Quickstart Example Question
                    jbertram

                    Here's a bit of code you can use in a client running within JBoss AS7 to look-up JMS resources:

                     

                            Context context = new InitialContext();

                            ConnectionFactory connectionFactory = (ConnectionFactory) context.lookup("java:/JmsXA");

                            Destination destination = (Destination) context.lookup("java:/queue/test");

                            context.close();

                     

                    Note: I'm using the JmsXA connection factory here because it is more efficient to use this in an inVM client since it is pooled.

                    • 7. Re: MDB Quickstart Example Question
                      jbertram

                      Yes, he can turn his POJO into an EJB and use injection if desired.

                      • 8. Re: MDB Quickstart Example Question
                        foutjo

                        Thanks Justin.

                         

                        Changing my POJO to use the sample code you gave me enabled it to write to the message queue.

                        The only other change I had to make was to include the destination in the messageProducer.send call.

                         

                        In your last answer would this indicate that if I were to make my POJO a SLSB then I would have been

                        able to use the same code that I origianlly had?

                        If yes is then one method perferred over the other?  Lets say for performance reasons?

                         

                        Here is what my final code looked like:

                         

                         

                        Context context = new InitialContext();

                        ConnectionFactory connectionFactory = (ConnectionFactory) context.lookup("java:/JmsXA");

                        Destination destination = (Destination) context.lookup("java:/queue/test");

                        context.close();

                        connection = connectionFactory.createConnection();

                        Session session = connection.createSession(false,

                                    Session.AUTO_ACKNOWLEDGE);

                        MessageProducer messageProducer = session.createProducer(queue);

                        connection.start();

                                

                        TextMessage message = session.createTextMessage();

                        for (int i = 0; i < 5; i++) {

                            message.setText("This is message " + (i + 1));

                            messageProducer.send(destination,message);

                         

                         

                        Thanks again Justin and Noa for your help.

                        • 9. Re: MDB Quickstart Example Question
                          jbertram

                          The only other change I had to make was to include the destination in the messageProducer.send call.

                          You don't have to do it this way.  Your call to javax.jms.Session.createProducer(Destination) should use the javax.jms.Destination you looked up in JNDI.  You are using a variable named "queue" which I don't see defined.  Also, you don't need to invoke javax.jms.Connection.start() as this only applies to consumers.  For example:

                           

                            Context context = new InitialContext();

                            ConnectionFactory connectionFactory = (ConnectionFactory) context.lookup("java:/JmsXA");

                            Destination destination = (Destination) context.lookup("java:/queue/test");

                            context.close();

                            connection = connectionFactory.createConnection();

                            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

                            MessageProducer messageProducer = session.createProducer(destination);

                            TextMessage message = session.createTextMessage();

                            for (int i = 0; i < 5; i++) {

                                message.setText("This is message " + (i + 1));

                                messageProducer.send(message);

                            }

                           

                          In your last answer would this indicate that if I were to make my POJO a SLSB then I would have been able to use the same code that I origianlly had?

                          If yes is then one method perferred over the other?  Lets say for performance reasons?

                          If you made your POJO an SLSB then you would be able to use injection because injection is valid for an SLSB whereas injection is not valid for a POJO.  Injection requires a bit less application code than the normal JNDI look-up pattern, and for that reason it is generally preferred.  However, changing your POJO into an SLSB may not be what you want to do (for whatever reason).  Performance really isn't a factor when deciding whether or not to use injection.  However, performance can definitly be a factor when deciding on a POJO vs. SLSB since SLSBs are pooled and can oftentimes provide a better QOS than POJOs.  It all depends on how you're using this code.

                          1 of 1 people found this helpful
                          • 10. Re: MDB Quickstart Example Question
                            foutjo

                            Thanks Justin for that helpful explanation.

                            You have been a big help!!!

                            • 11. Re: MDB Quickstart Example Question
                              foutjo

                              I am finally getting to try writing a message from a POJO.

                               

                              I keep getting name not found error for the queue name.

                               

                              10:31:20,189 ERROR [stderr] (EJB default - 2) javax.naming.NameNotFoundException: java:queue/admhcontrol

                               

                              Here is what I have:

                               

                              standalone-full.xml

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

                              <jms-destinations>

                                 <jms-queue name="ADMHControlQueue">

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

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

                              </jms-topic>

                               

                              Server log shows this at startup

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

                               

                              10:30:33,711 INFO  [org.jboss.as.messaging] (MSC service thread 1-2) JBAS011601: Bound messaging object to jndi name java:jboss/exported/jms/queue/admhcontrol

                               

                               

                              Code in POJO to write to message queue:

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

                               

                              Context context = new InitialContext();

                              ConnectionFactory connectionFactory = (ConnectionFactory) context.lookup("java:/ConnectionFactory");

                              Destination destination = (Destination) context.lookup("java:queue/admhcontrol");              

                              context.close();

                               

                              connection = connectionFactory.createConnection();

                              session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

                               

                              MessageProducer messageProducer = session.createProducer(destination);

                              ObjectMessage objectMessage = session.createObjectMessage();

                              objectMessage.setObject(process);

                              messageProducer.send(objectMessage);

                               

                              Get the following error on the context.lookup:

                               

                              10:31:20,189 ERROR [stderr] (EJB default - 2) javax.naming.NameNotFoundException: java:queue/admhcontrol

                               

                               

                              Any help on this issue is greatly appreciated.

                               

                              Thanks

                              • 12. Re: MDB Quickstart Example Question
                                jbertram

                                The NameNotFoundException you are receiving is accurate.  You don't have a JMS queue bound to "java:queue/admhcontrol". Anything bound in the "java:jboss/exported" namespace is exposed to remote clients - that's what this namespace is for.  A remote client would look it up by using whatever comes after "java:jboss/exported".  For example, a remote client would look-up this queue by using "jms/queue/admhcontrol".  If you wanted to look it up locally using this entry you'd use "java:jboss/exported/jms/queue/admhcontrol".

                                 

                                If you want your queue bound to "java:queue/admhcontrol" then define it like this:

                                 

                                <jms-queue name="ADMHControlQueue">
                                   <entry name="java:jboss/exported/jms/queue/admhcontrol"/>
                                   <entry name="java:queue/admhcontrol"/>
                                </jms-queue>
                                
                                • 13. Re: MDB Quickstart Example Question
                                  foutjo

                                  Thanks Justin it worked like a charm.

                                  Thanks also for the explaining how it works.

                                  • 14. Re: MDB Quickstart Example Question
                                    jbertram

                                    FYI - I updated the documentation to hopefully make this more clear up front.