Discussions

EJB programming & troubleshooting: Startup class for Message Driven bean listening to IBM MQ

  1. Hello Friends,

    I am trying to deploy a Message driven bean on weblogic 7.0 which would act as a listener for IBM MQ. I understand that a start-up class is required.

    Can someone give me a sample code for a start-up class and the deployement descriptors. I am able to register the factory but i do not know how to register the Queue in the Weblogic JNDI.

    All help would be appreciated,

    Thanks and regards,

    Milan Doshi

    Threaded Messages (8)

  2. please read weblogic doc and sample.

    C:\bea\weblogic700\samples\server\src\examples\startup

    public class StartBrowser implements T3StartupDef
    {


       public String startup(String name, Hashtable args) throws Exception
        {
           String p = (String)args.get("port");
        }
    }

    config.xml

         <StartupClass ClassName="examples.rmi.hello.HelloImpl"
            FailureIsFatal="false" Name="hello"/>
  3. Warning[ Go to top ]

    There is no coverage in the J2EE specs for JTA integration between MDBs and foreign JMS provides (in your case MQ Series). Once you have your queue set up in JNDI and have your bean receiving messages, you will notice strange behaviour in the acknowledgement of messages if you use CMT. The idea with CMT with MDB is that the message acknowledgement is part of the transaction, however due to the spec shortfall you'll find that all messages are acknowledge, or redelivered (I can't remember which way round it is) regarless of failure or success. There are a couple of ways round this, the simplest and most popular seems to be the message briding patter, where you have a WLS queue driving your bean and you have a message transfer client app that reads from the MQ queue and sends the message to the WLS driving queue. The alternative is to use BMT, but this approach is a can of worms.

    You should only need a simple JNDI bind to get your admin objects (CF and queue) in JNDI.
  4. Warning[ Go to top ]

    \Robinson\
    There is no coverage in the J2EE specs for JTA integration between MDBs and foreign JMS provides (in your case MQ Series). Once you have your queue set up in JNDI and have your bean receiving messages, you will notice strange behaviour in the acknowledgement of messages if you use CMT. The idea with CMT with MDB is that the message acknowledgement is part of the transaction, however due to the spec shortfall you'll find that all messages are acknowledge, or redelivered (I can't remember which way round it is) regarless of failure or success.
    \Robinson\

    I believe you can get the correct behavior if your JMS provider and database driver are XA compliant. In that case the container could control both via a global XA transaction.

    Of course this will normally involve a performance penalty, and not all JMS providers or database drivers are XA compliant (or are buggy). But if XA is doable for you, then there is an entirely in-spec solution.

        -Mike
  5. Warning[ Go to top ]

    /Mike/
    > I believe you can get the correct behavior if your JMS provider and database driver are XA compliant. In that case the container could control both via a global XA transaction.
    >
    > Of course this will normally involve a performance penalty, and not all JMS providers or database drivers are XA compliant (or are buggy). But if XA is doable for you, then there is an entirely in-spec solution.
    /Mike/

    Mike,

    The XA support doesn't make any difference. The problem is that there is no way to retrospectively inject the providers transaction into that which is started in the MDB when the onMessage method starts.

    If this was the case, then there wouldn't be the need for the bridge pattern.

    If you use the same suppliers JMS provider and TM then they will likely provide an undercover, non portable solution.

    I suspect that at least BEA have done the decent thing and at least tried to alert the Bean Provider when he tried to drive the MDB using a foreign provider - as Milan quotes in the thfead after this.

    Aaron
  6. Context ctx = new InitialContext();

    MQQueueConnectionFactory factory = new MQQueueConnectionFactory();

    String hostName = "1.5.1.46";
    factory.setHostName(hostName);

    String queueManager = "manager";
    factory.setQueueManager(queueManager);

    QueueConnection connection = factory.createQueueConnection();

    QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);



    String qcf = "MQConnectionFactory";
    ctx.bind(qcf, factory);

    String queueName = "G";
    Queue ioQueue = session.createQueue(queueName);

    String qname = "MQQueue";
    ctx.bind(qname, ioQueue);
  7. Whare am I going wrong?[ Go to top ]

    Hello,

    Thanks everyone for the response.

    I have written the startUp class with the help of M Ramu`s feedback. I am getting the following error:

    The Error was:
    The JMS destination with the JNDI name: MySenderQueue could not be found. Please ensure that the
     JNDI name in the weblogic-ejb-jar.xml is correct, and the JMS destination has been deployed.>

    =====

    My startup class is as follows:

    String qmPort = (String)args.get(QM_PORT_PROPERTY);
    String qmHost = (String)args.get(QM_HOST_PROPERTY);
    String qmName = (String)args.get(QM_NAME_PROPERTY);

    MQQueueConnectionFactory factory = new MQQueueConnectionFactory();

    factory.setQueueManager(qmName);
    factory.setHostName(qmHost);
    if (qmPort != null)
    {
        try
        {
            int portNum = Integer.parseInt(qmPort);
            factory.setPort(portNum);
        }
        catch (NumberFormatException ignore)
        {

        }
    }
    if (qmHost == null)
    {
        factory.setTransportType(JMSC.MQJMS_TP_BINDINGS_MQ);


    }
    else
    {
     factory.setTransportType(JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);
    }

     InitialContext context = new InitialContext();
     context.bind(jndiName, factory);
     
     QueueConnection connection = factory.createQueueConnection();
     boolean transacted = false;
     QueueSession session = connection.createQueueSession( transacted,
                    Session.AUTO_ACKNOWLEDGE);
     Queue ioQueue = session.createQueue("MySenderQueue");
     
     context.bind("MySenderQueue",ioQueue);
     context.close();
            

    ===================================================

    My Weblogic-ejb-jar.xml is like this:

    <weblogic-ejb-jar>
    <weblogic-enterprise-bean>
    <ejb-name>SimpleMDB</ejb-name>
    <message-driven-descriptor>
    <pool>
    <max-beans-in-free-pool>8</max-beans-in-free-pool>
    <initial-beans-in-free-pool>1</initial-beans-in-free-pool>
    </pool>
    <destination-jndi-name>MySenderQueue</destination-jndi-name>
    <!-- The next three elements are not necessary if the JMS that is driving this message-driven bean is WebLogic Server. -->
    <initial-context-factory>
                    com.sun.jndi.fscontext.RefFSContextFactory
                </initial-context-factory>
    <provider-url>
                    file:/D:/JNDI/
                </provider-url>
    <connection-factory-jndi-name>
                    MyQCF
                </connection-factory-jndi-name>
    </message-driven-descriptor>
    </weblogic-enterprise-bean>
    </weblogic-ejb-jar>

    ======================================================

    Can you please guide me what is wrong in registering the Queue?

    Thanks once again for the response,

    Milan Doshi
  8. Confusion regarding with Queue[ Go to top ]

    Hello M Ramu,

    Thanks for the earlier reply,

    I had one more queery:

    Can we create the Start-up class queue object using MQQueue class like this:

    MQQueue myQ =new MQQueue("queue://"+QmgrName+"/BridgeSenderQueue");
    context.bind("JNDIQueueName",myQ);

    OR whether I do it the way you have shown and it would work as well?

    Further also guide me on the XA Transaction part if you can.....
    http://www.theserverside.com/discussion/thread.jsp?thread_id=18950

    Thanks and regards,

    Milan Doshi
  9. Now I am developing a MDB in Weblogic8 and Tibco jms server. It running ok normally. But after restart the Tibco jms server, the MDB can not use the XA resource again. Is there some solution for this case? Thank you.