2 Replies Latest reply on Sep 16, 2009 12:15 PM by ben.cotton2

    How to code access to JBossAS5 JCA Resource TxConnectionFact

    ben.cotton2


      I am trying to write Java application code that will access a JBoss AS 5 deployed JCA Resource TxConnectionFactory instance.

      I added the added the JCA Resource TxConnectionFactory via the JBoss AS Administgration Console. Both the JBoss 5.1GA server log and the JBoss AS Administration Console show the instance as 'UP' and status='available'.

      The JCA Resource TxConnectionFactory was added via the console with the following configuration parameter values.

      JNDI Name= mqCF
      RAR Name= wmq.jmsra.rar
      ConnectionDefinition= javax.jms.ConnectionFactory
      MinPoolSize=1
      MaxPoolSize=10
      XATransaction=Yes


      // all the other Resource config values are either unset or default

      Resource 'Config Property' Settings:
      channel java.lang.String S_nyfilw007459
      hostName java.lang.String 10.9.60.107
      port java.lang.String 1414
      queueManager java.lang.String QM_nyfilw007459
      transportType java.lang.String CLIENT
      


      Again, both the server log and the AS Admin console show the 'mqCF' JCA Resource TxConnectionFactory as 'UP' and status='available'.

      How do I write Java app code to access this TxConnection Factory?

      The following code fails with this message at the top of the Exception stack:

      "javax.naming.NameNotFoundException: mqCF not bound"


      Here is the code that produced that message:





      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"); //Linux
      
      
       Context ctx = new InitialContext(props);
      
      
       ConnectionFactory factory = (ConnectionFactory)ctx.lookup("mqCF");
      
       System.out.println("'mqCF' ConnectionFactory established! mqCF.hashCode=["+factory.hashCode()+"]");
      


        • 1. Re: How to code access to JBossAS5 JCA Resource TxConnection
          jaikiran

          Looking at that screen on admin-console, the "JNDI Name" property description looks incorrect. It says:

          The global JNDI name to bind the connection factory under.


          IMO, its not completely true, because binding in the global JNDI namespace is governed by the other property "Use Java Context" on that page:

          Indicates whether the JNDI name should be bound under the "java" context, which causes the DataSource to only be accessible from within the JBossAS VM. The default is Yes.


          So i guess, the connection factory was created with the following configuration:

          <use-java-context>true</use-java-context>


          You can edit the generated xml file to set that property to false and restart the server. Then your java standalone app can look it up in the global jndi namespace.


          • 2. Re: How to code access to JBossAS5 JCA Resource TxConnection
            ben.cotton2

            Thanks! that was helpful ... I am no longer getting the " 'mqCF' not bound" exception message and my app code is now able to successfully lookup my JBoss 5 hosted 'mqCF' JCA Resource TxConnectionFactory instance.

            Only problem is that for this line of code, the value returned for the 'mqCF' lookup is NULL.

            ConnectionFactory factory = (ConnectionFactory)ctx.lookup("mqCF");
            



            I tried to do some debugging to account for this. My $JB5/server/default/deploy/mqCF-ds.xml file looks exactly like this:

            
            <connection-factories>
            
            
             <mbean code="org.jboss.resource.deployment.AdminObject" name="jca.wmq:name=MQ.HOSTED.QUEUE.JBOSS.BRIDGED">
             <attribute name="JNDIName">MQ.HOSTED.QUEUE.JBOSS.BRIDGED</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=QM_nyfilw007459
             baseQueueName=MQ.HOSTED.QUEUE.JBOSS.BRIDGED
             <!-- expiry=EXP_UNLIMITED -->
             </attribute>
             </mbean>
            
             <tx-connection-factory>
             <jndi-name>mqCF</jndi-name>
             <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"> S_nyfilw007459</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">QM_nyfilw007459</config-property>
             <config-property type="java.lang.String" name="transportType">CLIENT</config-property>
             <security-domain xsi:type="securityMetaData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
             <metadata/>
             <xa-resource-timeout>0</xa-resource-timeout>
             <xa-transaction/>
             </tx-connection-factory>
            </connection-factories>
            



            Note that I do include a correct config of the IBM Websphere MQ JCA RAR file = 'wmq.jmsra.rar'.

            However, when I go the JBoss 5 JMX console and look up the run-time value of my deployed JMX MBean=jca.wmq
            I see the following *Incorrect* run-time vaule for the 'RARname' property:

            RARName RW javax.management.ObjectName MBean Attribute.
            jboss.jca:service=RARDeployment,name=
            
            


            (NOTE: the 'name' R-value is NULL not 'wmq.jmsrar.rar')

            Could this account for why my 'mqCF' lookup is returning NULL? Could it be a JBoss bug that accounts for the JMX view not showing the correct 'wmq.jmsrar.rar' value ( that seems to be correctly specified in the mqCF-ds.xml file ) ?


            Ultimately, I want to use IBM Websphere MQ's JCA RAR (deployed to JBOSS as a Resource) to achieve the capability for JBOSS components to publish to an MQ destination via a JBOSS named connection factory. This is the full (very simple) app 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);
            
            
             ConnectionFactory factory = (ConnectionFactory)ctx.lookup("mqCF");
             System.out.println("'mqCF' ConnectionFactory established! mqCF=["+factory+"]");
             Connection conn = factory.createConnection();
            
             javax.jms.Queue myQueue = (javax.jms.Queue)ctx.lookup("MQ.HOSTED.QUEUE.JBOSS.BRIDGE");
             Session session = conn.createSession(false,Session.AUTO_ACKNOWLEDGE);
             MessageProducer mp = session.createProducer(myQueue);
             TextMessage tm = session.createTextMessage();
            
            
             tm.setText("Message =(" + args[1].toString() + ")");
             mp.send(tm);
             System.out.println("Sent MSG=["+tm.getText()+"] to JBoss QUEUE=["+myQueue.getQueueName()+"]");
            
            


            Does this seem like reasonable code to achieve this goal? The code draws from the JBoss Wiki documentation at http://www.jboss.org/community/wiki/UsingWebSphereMQSeriesWithJBossASPart4

            Note: Others posted comments at that Wiki page that they could not successfully execute the documentation instructions to publish to an MQ destination via looking up a JBoss hosted mqCF (configured to ref wmq.jmsra.rar).

            Is there better JBoss documentation to help an app programmer achieve this objective?

            Please confirm that what I am trying to do is indeed supported as a confirmed working capability in JBoss 5 (the Wiki posts seem to suggest others are having significant problems getting this to work).