6 Replies Latest reply on Feb 11, 2010 8:42 AM by Ben Cotton

    How to code JNDI lookup of JCA Resource ConnectionFactory?

    Ben Cotton Newbie

      I am trying to write a super-simple .java standalone app that looks up a JBoss JNDI-hosted ConnectionFactory (configured as JCA Resource). The ConnectionFactory (named 'IVTCF' and visible in my JBoss AS 5 Admin Console under Resource-->ConnectionFactory) is also configured (via a Resource Adapter) to JCA-connect to an IBM WS MQ hosted Queue.

      First step, to confirm that my JBoss AS 5 instance's JCA-connection plumbing to WS MQ was in working order, I installed IBM's WS MQ JCA Resource Installation and Verification Test (IVT) application (wmq.jmsra.ivt.ear) on my JBoss 5.1 AS instance.

      Second step, I ran the IBM IVT app's Servlet example (which also looks up the exact same JBoss JNDI hosted 'IVTCF' ConnectionFactory) and confirmed that 'IVTCF' correctly uses the configured JCA adapter to produce a Message on an IBM WS MQ hosted Queue.

      Thrid step, I ran the IBM IVT app's MDB example and confirmed that a JBoss deployed MDB can also consume Messages (via JCA) published to the exact same IBM WS MQ Queue.

      But I can't get my super-simple .java code's JNDI lookup of the exact same JBoss JNDI hosted 'IVTCF' ConnectionFactory to return a non-NULL value!

      Unfortunately, I don't have the IBM IVT.ear's .java source code so I don't have any explicit example of how this can be exactly written with (verified to be working) .java code.

      Here is my super-simple .java code.

      
      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 uses the exact same 'IVTCF' ConnectionFactory bound in my JBoss JNDI tree, but the runtime value of the JNDI lookup's 'factory' assignment is always NULL. And thus the last line of this code is always an NPE.

      Any suggestions on what I am doing wrong?

      Thanks.

        • 1. Re: How to code JNDI lookup of JCA Resource ConnectionFactor
          Vicky Kak Master

          Can you show us the connection factory deployment descriptor file?

          • 2. Re: How to code JNDI lookup of JCA Resource ConnectionFactor
            mariqn nenchev Novice

            I have similar problem with exactly the same case. But i am not getting null pointer exception. Instead i am getting ClassCastException when i try to lookup the QueueConnectionFactory and try to cast to ConnectionFactory it throws me an exception:
            java.lang.ClassCastException: com.ibm.mq.connector.outbound.ConnectionFactoryImpl cannot be cast to javax.jms.QueueConnectionFactory

            my wmq.jmsra.xml (deployed in /server/all/deploy):

            <?xml version="1.0" encoding="UTF-8"?>
            
            <connection-factories>
            
             <!-- connection factory definition -->
             <tx-connection-factory>
             <jndi-name>TESTCF</jndi-name>
             <xa-transaction />
             <rar-name>wmq.jmsra.rar</rar-name>
             <connection-definition>javax.jms.ConnectionFactory</connection-definition>
             <config-property name="channel" type="java.lang.String">TEST.CHANNEL</config-property>
             <config-property name="hostName" type="java.lang.String">192.168.2.100</config-property>
             <config-property name="port" type="java.lang.String">1414</config-property>
             <config-property name="queueManager" type="java.lang.String">TESTQM</config-property>
             <config-property name="transportType" type="java.lang.String">CLIENT</config-property>
             <security-domain-and-application>JmsXARealm</security-domain-and-application>
             </tx-connection-factory>
            
             <!-- admin object definition -->
             <mbean code="org.jboss.resource.deployment.AdminObject" name="jca.wmq:name=testqueue">
             <attribute name="JNDIName">testqueue</attribute>
             <depends optional-attribute-name="RARName">
             jboss.jca:service=RARDeployment,name='wmq.jmsra.rar'
             </depends>
             <attribute name="Type">javax.jms.Queue</attribute>
             <attribute name="Properties">
             baseQueueManagerName=TESTQM
             baseQueueName=testqueue
             expiry=EXP_UNLIMITED
             </attribute>
             </mbean>
            </connection-factories>
            


            Why the lookup returns me object of a class that do not implement QueueConnectionFactory?

            • 3. Re: How to code JNDI lookup of JCA Resource ConnectionFactor
              Vicky Kak Master

               

              "mnenchev" wrote:

              Why the lookup returns me object of a class that do not implement QueueConnectionFactory?


              Did you talk to IBM support about it?

              • 4. Re: How to code JNDI lookup of JCA Resource ConnectionFactor
                Ben Cotton Newbie

                Thanks Vicky.  Attached is the ConnectionFactory deployment descriptor.

                 

                Note:  If I code the following from a JBoss-deployed servlet, everything works perfectly ... the JBoss hosted JNDI references correctly uses the IBM JCA resource adapter to bridge to WSMQ implementations of Queue and QueueConnectionFactory.

                 

                            InitialContext ic = new InitialContext();
                       
                            javax.jms.ConnectionFactory cf = (javax.jms.ConnectionFactory) ic.lookup("IVTCF");
                            log.info("'IVTCF' javax.jms.ConnectionFactory found: [" + cf + "]");
                           
                            Queue q = (Queue) ic.lookup("IVTQueue");
                            log.info("'IVTQueue' javax.jms.Queue found: [" + q +"]");
                          
                           

                However, If I code the following from a standalone Java client app on a remote dektop machine, the ConnectionFactory lookup always results with 'factory' == NULL.

                 

                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+"]");

                 

                We have tried other JBoss forums suggested remedies ( http://community.jboss.org/thread/129674 ) but have not had success.

                 

                We would like a confirmation that, given the first block of code works correctly, we should reasonably expect the second block of code to also work correctly.  It is our belief that the fact that the second block of code does not work may be an indication of a JBoss bug.

                 

                (Attachment:  IVTCF-ds.xml)

                <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
                <connection-factories>


                    <mbean code="org.jboss.resource.deployment.AdminObject" name="jca.wmq:name=IVTQueue">     
                        <attribute name="JNDIName">/IVTQueue</attribute>
                        <depends optional-attribute-name="RARName">
                            jboss.jca:service=RARDeployment,name='wmq.jmsra.rar' </depends>
                        <attribute name="Type">javax.jms.Queue</attribute>
                        <attribute name="Properties">
                            baseQueueManagerName=CapMktsQM
                            baseQueueName=SYSTEM.DEFAULT.LOCAL.QUEUE </attribute>        
                    </mbean>

                    <tx-connection-factory>
                        <jndi-name>IVTCF</jndi-name>
                        <xa-transaction/>
                        <rar-name>wmq.jmsra.rar</rar-name>
                        <use-java-context>false</use-java-context>
                        <connection-definition>javax.jms.ConnectionFactory</connection-definition>
                        <jmx-invoker-name>jboss:service=invoker,type=jrmp</jmx-invoker-name>
                        <min-pool-size>1</min-pool-size>
                        <max-pool-size>10</max-pool-size>
                        <blocking-timeout-millis>30000</blocking-timeout-millis>
                        <idle-timeout-minutes>30</idle-timeout-minutes>
                        <prefill>false</prefill>
                        <background-validation>false</background-validation>
                        <background-validation-millis>0</background-validation-millis>
                        <validate-on-match>true</validate-on-match>
                        <statistics-formatter>org.jboss.resource.statistic.pool.JBossDefaultSubPoolStatisticFormatter</statistics-formatter>
                        <isSameRM-override-value>false</isSameRM-override-value>
                        <allocation-retry>0</allocation-retry>
                        <allocation-retry-wait-millis>5000</allocation-retry-wait-millis>
                        <config-property type="java.lang.String" name="channel">SYSTEM.DEF.SVRCONN</config-property>
                        <config-property type="java.lang.String" name="hostName">10.9.60.107</config-property>
                        <config-property type="java.lang.String" name="port">1414</config-property>
                        <config-property type="java.lang.String" name="queueManager">CapMktsQM</config-property>
                        <config-property type="java.lang.String" name="transportType">CLIENT</config-property>
                        <security-domain-and-application>JmsXARealm</security-domain-and-application>
                        <xa-resource-timeout>0</xa-resource-timeout>
                    </tx-connection-factory>
                </connection-factories>
                • 5. Re: How to code JNDI lookup of JCA Resource ConnectionFactor
                  Vicky Kak Master

                  Please enable the trace logging on JCA CM and let us know what you see from this code

                   

                  https://anonsvn.jboss.org/repos/jbossas/branches/Branch_4_2/connector/src/main/org/jboss/resource/connectionmanager/ConnectionFactoryBindingService.java

                   

                  I wanted to see what we get from ConnectionFactoryBinding::bindConnectionFactory .

                  1 of 1 people found this helpful
                  • 6. Re: How to code JNDI lookup of JCA Resource ConnectionFactor
                    Ben Cotton Newbie

                    Thanks for this reply Vicky.  Here is the TRACE level logging re: ConnectionFactoryBindingService activity ....

                     

                    Also, I have come to learn that I should not expect my

                     

                     

                    javax.jms.ConnectionFactory factory = (javax.jms.ConnectionFactory)ctx.lookup("IVTCF");

                     

                    statement to work when executied from a remote Java client application.  The JCA spec does not explicitly require that implementors accommodate a remote client's lookup of a ConnectionFactory JNDI reference that bridges to a providers ConnectionFactory implementation (via providers RA).   So the fact that JBoss does not accommodate my remote client's lookup of  'IVTCF' is definitely not an indication of any JBoss delinquency re: JCA compliance.  Indeed, wrt to a local client invoke, if I run the exact same lookup code from a JBoss deployed servlet everything works ideally.  That said, the above remote client lookup code is accommodated by the Apache Geronimo JEE implementation.  It would be mighty nice if JBoss AS also provided this accommodation.  I am considering opening a JBoss AS "feature enhancement" JIRA ticket re: this use case.  Thanks again Vicky.


                    cottonbe@dndcor3autw001> cat server.log | grep -i ConnectionFactoryBindingService
                    2010-02-11 06:11:15,134 DEBUG [org.jboss.resource.connectionmanager.ConnectionFactoryBindingService] (main) Binding object 'org.jboss.resource.adapter.jdbc.WrapperDataSource@1e58c9aa' into JNDI at 'java:DefaultDS'
                    2010-02-11 06:11:15,136 INFO  [org.jboss.resource.connectionmanager.ConnectionFactoryBindingService] (main) Bound ConnectionManager 'jboss.jca:service=DataSourceBinding,name=DefaultDS' to JNDI name 'java:DefaultDS'
                    2010-02-11 06:11:37,058 TRACE [org.jboss.resource.connectionmanager.ConnectionFactoryBindingService] (main) Constructing
                    2010-02-11 06:11:37,061 DEBUG [org.jboss.resource.connectionmanager.ConnectionFactoryBindingService] (main) Creating jboss.jca:service=ConnectionFactoryBinding,name=JmsXA
                    2010-02-11 06:11:37,061 DEBUG [org.jboss.resource.connectionmanager.ConnectionFactoryBindingService] (main) Created jboss.jca:service=ConnectionFactoryBinding,name=JmsXA
                    2010-02-11 06:11:37,061 DEBUG [org.jboss.resource.connectionmanager.ConnectionFactoryBindingService] (main) Starting jboss.jca:service=ConnectionFactoryBinding,name=JmsXA
                    2010-02-11 06:11:37,065 DEBUG [org.jboss.resource.connectionmanager.ConnectionFactoryBindingService] (main) Binding object 'org.jboss.resource.adapter.jms.JmsConnectionFactoryImpl@7ba37b98' into JNDI at 'JmsXA'
                    2010-02-11 06:11:37,065 INFO  [org.jboss.resource.connectionmanager.ConnectionFactoryBindingService] (main) Bound ConnectionManager 'jboss.jca:service=ConnectionFactoryBinding,name=JmsXA' to JNDI name 'JmsXA'
                    2010-02-11 06:11:37,065 DEBUG [org.jboss.resource.connectionmanager.ConnectionFactoryBindingService] (main) Started jboss.jca:service=ConnectionFactoryBinding,name=JmsXA
                    2010-02-11 06:11:38,906 DEBUG [org.jboss.resource.connectionmanager.ConnectionFactoryBindingService] (main) Binding object 'org.jboss.resource.adapter.jdbc.WrapperDataSource@14db02c9' into JNDI at 'java:ms-capmktsLocalTxDS'
                    2010-02-11 06:11:38,906 INFO  [org.jboss.resource.connectionmanager.ConnectionFactoryBindingService] (main) Bound ConnectionManager 'jboss.jca:service=DataSourceBinding,name=ms-capmktsLocalTxDS' to JNDI name 'java:ms-capmktsLocalTxDS'
                    2010-02-11 06:11:40,852 DEBUG [org.jboss.resource.connectionmanager.ConnectionFactoryBindingService] (main) Binding object 'org.jboss.resource.adapter.jdbc.WrapperDataSource@250e74de' into JNDI at 'java:pg-capmktsLocalTxDS'
                    2010-02-11 06:11:40,853 INFO  [org.jboss.resource.connectionmanager.ConnectionFactoryBindingService] (main) Bound ConnectionManager 'jboss.jca:service=DataSourceBinding,name=pg-capmktsLocalTxDS' to JNDI name 'java:pg-capmktsLocalTxDS'
                    2010-02-11 06:11:58,020 TRACE [org.jboss.resource.connectionmanager.ConnectionFactoryBindingService] (main) Constructing
                    2010-02-11 06:11:58,023 DEBUG [org.jboss.resource.connectionmanager.ConnectionFactoryBindingService] (main) Creating jboss.jca:service=ConnectionFactoryBinding,name=IVTCF
                    2010-02-11 06:11:58,023 DEBUG [org.jboss.resource.connectionmanager.ConnectionFactoryBindingService] (main) Created jboss.jca:service=ConnectionFactoryBinding,name=IVTCF
                    2010-02-11 06:11:58,023 DEBUG [org.jboss.resource.connectionmanager.ConnectionFactoryBindingService] (main) Starting jboss.jca:service=ConnectionFactoryBinding,name=IVTCF
                    2010-02-11 06:11:58,026 DEBUG [org.jboss.resource.connectionmanager.ConnectionFactoryBindingService] (main) Binding object 'com.ibm.mq.connector.outbound.ConnectionFactoryImpl@518add92' into JNDI at 'IVTCF'
                    2010-02-11 06:11:58,026 INFO  [org.jboss.resource.connectionmanager.ConnectionFactoryBindingService] (main) Bound ConnectionManager 'jboss.jca:service=ConnectionFactoryBinding,name=IVTCF' to JNDI name 'IVTCF'
                    2010-02-11 06:11:58,026 DEBUG [org.jboss.resource.connectionmanager.ConnectionFactoryBindingService] (main) Started jboss.jca:service=ConnectionFactoryBinding,name=IVTCF