8 Replies Latest reply on Sep 22, 2009 5:15 AM by Yong Hao Gao

    Easiest way to bind IBM WS MQ hosted 'Queue' to name in JBos

    Ben Cotton Newbie

      Given an IBM WSMQ 6.x hosted 'Queue' instance (MANAGER, QUEUE NAME, CHANNEL all explicitly identified with values), what is the easiest way to bind this specific 'Queue' to a NAME in a JBoss 5.x hosted JNDI tree?

      I've already copied the WSMQ provided wmq.jmsra.rar to my $JB/server/default/deploy/directory/

      but don't know how to easily proceed from here. By any chance is there a way to just use the JBoss admin console and navigate to

      Resource->JMS Destination->Queue->Add New

      and some how take advantage of the wmq.jmsra.rar resource to bind to a 'Queue' name in JBoss hosted JNDI? Or must I necessarily configure "by hand" multiple XML files?

      I am hopeful there may be an easier way than the steps described at
      http://www.jboss.org/community/wiki/UsingWebSphereMQSeriesWithJBossASPart4

        • 2. Re: Easiest way to bind IBM WS MQ hosted 'Queue' to name in
          Ben Cotton Newbie

          I have successfully deployed and executed IBM's WSMQ JCA Resource Installation and Verification Test application (wmq.jmsra.ivt.ear) on my JBoss 5.1 AS instance.

          The IVT app establishes on my JBoss instance a Resource-->ConnectionFactory-->TxConnectionFactory named 'IVTCF' that is visible from my JBoss 5 Admin console. Running the IVT app's Servlet example confirms that JMS code referencing the 'IVTCF' correctly uses the configured JCA adapter to produce a Message on an IBM WS MQ hosted Queue. Running the IVT app's MDB example confirms that I can also consume Messages from the exact same IBM WS MQ Queue.

          Unfortunately, I don't have the IVT.ear .java source code so I don't have an explicit example of how this is achieved with explicit JMS code. I tried to execute the following producer, using the same 'IVTCF' TxConnectionFactory, but the runtime value of the 'factory' assignment always NULL. And thus the last line of this code is always an NPE.



          
          Properties props = new Properties();
           props.setProperty(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
           props.setProperty(Context.PROVIDER_URL,"jnp://10.4.164.105:11099");
          
          
           Context ctx = new InitialContext(props);
          
          
           javax.jms.ConnectionFactory factory = (javax.jms.ConnectionFactory)ctx.lookup("IVTCF");
          
           // 'factory' always value = NULL at his time, why?
           System.out.println("'IVTCF' ConnectionFactory established! IVTCF=["+factory+"]");
          
           //NPE
           Connection conn = factory.createConnection();
          


          This code is using the exact same 'IVTCF' ConnectionFactory used by the IVT.ear servlet and MDB (both of which run successfully).

          Any suggestions on what might be wrong with the above code segment?


          • 3. Re: Easiest way to bind IBM WS MQ hosted 'Queue' to name in
            Yong Hao Gao Master

            Did you set this jndi property ?

            java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces

            • 4. Re: Easiest way to bind IBM WS MQ hosted 'Queue' to name in
              Ben Cotton Newbie

              Thanks for your reply gaohoward.

              I modified the code as you indicated:

               Properties props = new Properties();
               props.setProperty(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
               props.setProperty(Context.PROVIDER_URL,"jnp://10.4.164.105:11099");
              
              
              
               props.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
              
              
               Context ctx = new InitialContext(props);
              
              
               ConnectionFactory factory = (ConnectionFactory)ctx.lookup("IVTCF");
              
               System.out.println("looked up 'IVTCF' javax.jms.ConnectionFactory established! 'factory'=["+
               factory+
               "]");
              
              


              But I still only get 'factory' values == NULL after executing the lookup().

              Via the JBoss admin console, I checked the value for 'IVTCF' in the JNDI global namespace and it shows a correct and expected value.


              Global JNDI Namespace
              
              
               +- IVTCF (class: com.ibm.mq.connector.outbound.ConnectionFactoryImpl)
              




              I guess in the worst case, I could code this Producer to directly invoke the WS MQ implementation of com.ibm.msg.client.jms.JmsConnectionFactory, but I was hoping I could just deploy the WS MQ JCA Resource adapter to my JBoss instance, config a Resource-->ConnectionFactory via the JBoss admin console, and then just do a 'lookup' on that ConnFactory to have all the plumbing (from JBoss to WS MQ) done for me transparently (via JCA).

              Hoping to avoid coding directly to com.ibm.msg.client.jms.* API, do you have any other ideas/recommendations on how I might be able to get this to work via JBoss/JCA?

              • 5. Re: Easiest way to bind IBM WS MQ hosted 'Queue' to name in
                Ben Cotton Newbie

                FYI, I have a reasonably manageable workaround (though not ideal).

                When I code the exact same .lookup() logic from a JBoss-deployed servlet (instead of from an external app), everything works perfectly. This is obviously because the internal InitialContext construction needs no Context.XXX properties set.

                
                
                 InitialContext ic = new InitialContext(); // no Context.XXX props!! Now everything works via JCA!
                
                 javax.jms.ConnectionFactory cf = (javax.jms.ConnectionFactory) ic.lookup("IVTCF");
                 // confirm that we found the CF
                 log.info("'IVTCF' javax.jms.ConnectionFactory found: [" + cf + "]");
                 // get the queue
                 Queue q = (Queue) ic.lookup("IVTQueue");
                 // confirm that we found the queue
                 log.info("'IVTQueue' javax.jms.Queue found: [" + q +"]");
                


                Now the 'cf' value is NON-NULL and I can indeed publish to an IBM WS MQ destination from a JBoss component just by looking up a Resource-->ConnectionFactory ... and then relying on the JCA resource adapter to transparently manage all the messaging plumbing. :-)

                I still can't do this from an external stand-alone application that parameterizes its JBoss InitialContext() construction with Properties, but I'll live with that for now (or maybe post the issue to a JNDI focused forum).



                • 6. Re: Easiest way to bind IBM WS MQ hosted 'Queue' to name in
                  Anil Reddy Newbie

                  I am not sure, but it looks like the connection factory is bound in the java namespace, instead of the global JNDI.

                  You can view the jndi tree from the jmx-console.

                  • 7. Re: Easiest way to bind IBM WS MQ hosted 'Queue' to name in
                    Ben Cotton Newbie

                    Thanks for the reply.

                    The IVTCF-ds.xml includes the explicit config

                    <use-java-context>false</use-java-config>

                    Also, the JMX-Console JNDIView 'list' operation confirms that "IVTCF" is bound in the JNDI Global Namespace.

                    It remains puzzling that when I parameterize the InitialContext with Properties (from an extermal stand-alone application) that the

                    ConnectionFactory cf = ic.lookup("IVTCF");
                    invoke always returns NULL.

                    • 8. Re: Easiest way to bind IBM WS MQ hosted 'Queue' to name in
                      Yong Hao Gao Master

                      another thing to check is the connection-factory-service.xml, see what the JNDIBindings for it. sth like:

                       <attribute name="JNDIBindings">
                       <bindings>
                       <binding>/IVTCF</binding>
                       </bindings>
                       </attribute>