14 Replies Latest reply: May 3, 2012 4:37 PM by Justin Bertram RSS

MDB Quickstart Example Question

Joseph Fouts Novice

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
    Noa Drach Novice

    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
    Joseph Fouts Novice

    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
    Justin Bertram Master

    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
    Joseph Fouts Novice

    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
    Noa Drach Novice

    so SLSB will be achived by annotating MessageConn with @Stateless

  • 6. Re: MDB Quickstart Example Question
    Justin Bertram Master

    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
    Justin Bertram Master

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

  • 8. Re: MDB Quickstart Example Question
    Joseph Fouts Novice

    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
    Justin Bertram Master

    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.

  • 10. Re: MDB Quickstart Example Question
    Joseph Fouts Novice

    Thanks Justin for that helpful explanation.

    You have been a big help!!!

  • 11. Re: MDB Quickstart Example Question
    Joseph Fouts Novice

    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
    Justin Bertram Master

    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
    Joseph Fouts Novice

    Thanks Justin it worked like a charm.

    Thanks also for the explaining how it works.

  • 14. Re: MDB Quickstart Example Question
    Justin Bertram Master

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