1

My project are built based on websphere 8.5 and we decided to use JMS quque for message within my project.

So, I createad a bus named MyBus, also created a destination myBusDistination.

Then I created a Connection Factory named myConF

Then I created two JMS queues, one is myQueue1 with JNDI jndi/myQueue1. The other one is myQueue2 with JNDI jndi/mQueue2.

Then I created two Activation specifications, one is myAS1 with JNDI jndi/myAS1, the other is myAS2 with JNDI jndi/myAS2.

Then I created two message driven beans and they are in EJB3.0, named MyMDB1 and MyMDB2. The class code is like this,

@MessageDriven(mappedName = "jndi/myQueue1", activationConfig = {     @ActivationConfigProperty(propertyName = "destinationType", propertyValue     = "javax.jms.Queue") })
public class MyMDB1 implements MessageListener {
    @Override
    public void onMessage(Message message) {
    }
}

The ejb_jar.xml is like this,

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns="http:/java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee      http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"
version="3.0" metadata-complete="false">
<display-name>My MDB</display-name>
<enterprise-beans>

    <message-driven>
        <display-name>MyMDB1</display-name>
        <ejb-name>MyMDB1</ejb-name>
        <ejb-class>com.test.mdb.MyMDB1</ejb-class>
        <message-destination-ref>
            <message-destination-ref-name>jndi/myQueue1</message-destination-ref-name>
            <message-destination-type>javax.jms.Queue</message-destination-type>
            <message-destination-usage>Consumes</message-destination-usage>
            <message-destination-link>jndi/myQueue1</message-destination-link>
        </message-destination-ref>
    </message-driven>

    <message-driven>
        <display-name>MyMDB2</display-name>
        <ejb-name>MyMDB2</ejb-name>
        <ejb-class>com.test.mdb.MyMDB2</ejb-class>
        <message-destination-ref>
            <message-destination-ref-name>jndi/myQueue2</message-destination-ref-name>
            <message-destination-type>javax.jms.Queue</message-destination-type>
            <message-destination-usage>Consumes</message-destination-usage>
            <message-destination-link>jndi/myQueue2</message-destination-link>
        </message-destination-ref>
    </message-driven>
</enterprise-beans>

And the ibm-ejb-jar-bnd.xml is like this,

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar-bnd xmlns="http://websphere.ibm.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-ejb-jar-bnd_1_0.xsd"
version="1.0">

<message-driven name="MyMDB1">
    <jca-adapter activation-spec-binding-name="jndi/myAS1" destination-binding-name="jndi/myQueue1"/>
    <message-destination-ref name="jndi/myQueue1" binding-name="jndi/myQueue1" />
</message-driven>

<message-driven name="MyMDB2">
    <jca-adapter activation-spec-binding-name="jndi/myAS2" destination-binding-name="jndi/myQueue2"/>
    <message-destination-ref name="jndi/myQueue2" binding-name="jndi/myQueue2" />
</message-driven>

At last, here is the code for my test,

Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY,
      "com.ibm.websphere.naming.WsnInitialContextFactory");
props.put(Context.PROVIDER_URL, "corbaloc:iiop:localhost:2809");               InitialContext ctx = new InitialContext(props);
ConnectionFactory factory = (ConnectionFactory) ctx.lookup("jndi/myConF"); 
        Destination destination = (Destination) ctx.lookup("jndi/myQueue1");  
        Connection conn = factory.createConnection(); 
        Session session = conn.createSession(false, QueueSession.AUTO_ACKNOWLEDGE); 
        MessageProducer producer = session.createProducer(destination);

                    ObjectMessage objMsg = session.createObjectMessage();
        objMsg.setObject("MDB Test");

        producer.send(objMsg); 
        session.close();
        conn.close();

The strange thing is,

Message can be sent out, and the message can be processed by MDB MyMDB1(if I log something within MyMDB1.onMesssage()). But if I send the message again. the message will be processed by MyMDB2.

Anyone have some ideas on this 'strange thing'?

ᄂ ᄀ
  • 5,669
  • 6
  • 43
  • 57
zhianABCD
  • 223
  • 1
  • 4
  • 15

2 Answers2

1

As i understand, you created two JMS queues (jndi/myQueue1, jndi/myQueue2) which was connected to the same destination. That is why both MDBs waiting for a message from that destination. As a result which one takes the message from queue faster will run. This is a bad practice. And in your test you only put message into destination using jndi/myQueue1 and jndi/myAS1, but it doesn't mean. You can try to stop one of your MDBs and after that you can see that will work only another one, and messages will not stay in queue.

Update. If need two different queues to receive different messages. You should make something like this:

  1. Create second destination named, for example, myDestination2.
  2. Change configuration of your myQueue2(Resourses->JMS->Queues). In Connection block change 'Queue name' from myBusDistination to the myDestination2.
  3. To put message for the second MDB use:

    ConnectionFactory factory = (ConnectionFactory) ctx.lookup("jndi/myConF"); Destination destination = (Destination) ctx.lookup("jndi/myQueue2");

    to put messages to the first one nothing changes:

    ConnectionFactory factory = (ConnectionFactory) ctx.lookup("jndi/myConF"); Destination destination = (Destination) ctx.lookup("jndi/myQueue1");

IRomanov
  • 42
  • 6
  • Yes, you are probably right, do you have any idea that to make both of the queues are working at the same time? Since I need to create 2 queues to receive the messages – zhianABCD Jul 09 '15 at 10:41
  • If you have WebSphere MQ you can put message into topic and make subscription for 2 different queues. In your situation you can make one MDB which will run to different beans with business logic. Or if it is possible you can make 2 different destination on your bus and put message in both. – IRomanov Jul 09 '15 at 10:54
  • Hi IRomanov, I need JMS quque till now, and I need to create queues to receive different messages, what I can not understand is, I already put myQueue1 for JNDI lookup, why the message is also processed by MyMDB2? is that because they are specified to the same Queue Name? myDesination1? if I create another destination myDestination2 to myQueue2, what should I do for JNDI lookup? I mean, if I want to send message to myQueue1, and want to ask MyMDB1 to process the message, I should put myQueue1 for JNDI lookup or myDestination1 for JNDI lookup? – zhianABCD Jul 10 '15 at 01:07
  • I have updated the answer. You should use `jndi/myQueue1` and `jndi/myQueue2` for JNDI lookups. Is it what you want? – IRomanov Jul 10 '15 at 09:33
0

You have to create one bus destination per queue, so in your case myBusDistination1 for queue1 and myBusDistination2 for queue2. Then when you will send to queue1 MDB1 will receive the message and if you will send to queue2, MDB2 will receive the message. If you want all MDBs receive same message you will have to create topic not queue, and activation specs pointing to the topic.

You didn't specify in the question what actually you are trying to achieve.

Gas
  • 17,601
  • 4
  • 46
  • 93
  • Hi Gas, you are right, I only created one Bus and one Destination, as you know that, when creating JMS queue, we have to specify the Queue name, and I put myBusDistination1 to myQueue1 and myQueue2, but when I sending my message, I already give the myQueue1 for JNDI lookup, I really need two different queues, since I need to receive different messages. my question is, when I want to send my message, for JNDI lookup, What should I put the value there? I mean myQueue1 or myDestination1? – zhianABCD Jul 10 '15 at 01:02
  • @zhianABCD you need to create 2 different destinations on the bus. Why you are putting same destination to different queues? – Gas Jul 10 '15 at 19:58