2 Replies Latest reply on Dec 16, 2009 6:08 PM by Anuj Upadhyay

    MDB does not pick up connection factory settings

    Paul Pacheco Newbie

      I am using jboss 5.0.1, and websphere 6

      I want to develop an MDB and have it connect to a queue in websphere.
      I followed the instructions from here:
      http://www.jboss.org/community/docs/DOC-12535
      and was successfull. My MDB connected to the queue and everything worked.

      In that document, I am adviced to put some queue properties inside ejb-jar.xml or I can do it with annotations. My problem is that both alternatives make the ejb non configurable, it is now hard coded to connect to a specific host and queue manager.

      I would like to get the queue configuration passed to the MDB via jndi, and then I would configure the connectionFactory and the destination on a xxx-ds.xml file. So far I have this:

      on my ds.xml file I have this:

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE connection-factories PUBLIC "-//JBoss//DTD JBOSS JCA Config 5.0//EN" "http://www.jboss.org/j2ee/dtd/jboss-ds_5_0.dtd">
      
      <connection-factories>
      
       <tx-connection-factory>
       <jndi-name>WSMQConnectionFactory</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">CASPERCHANNEL01</config-property>
       <config-property name="hostName" type="java.lang.String">my.host.com</config-property>
       <config-property name="port" type="java.lang.String">1420</config-property>
       <config-property name="queueManager" type="java.lang.String">TCASPER01</config-property>
       <config-property name="transportType" type="java.lang.String">CLIENT</config-property>
       <security-domain-and-application>JmsXARealm</security-domain-and-application>
       <max-pool-size>20</max-pool-size>
       </tx-connection-factory>
      
      
      
       <mbean code="org.jboss.resource.deployment.AdminObject" name="jboss.jca:service=WASDestination,name=QueueName">
       <depends optional-attribute-name="RARName">jboss.jca:service=RARDeployment,name='wmq.jmsra.rar'</depends>
       <attribute name="JNDIName">queue/pnr</attribute>
       <attribute name="Type">javax.jms.Queue</attribute>
       <attribute name="Properties">
       baseQueueManagerName=TCASPER01
       baseQueueName=AMR.RPT.DIRECT.PNR
       </attribute>
       </mbean>
      
      </connection-factories>
      


      This deploys correctly and I can see both the connectionFactory and the destination in the jndi tree from jmx-console.

      on my ejb I have this:

      import javax.ejb.ActivationConfigProperty;
      import javax.ejb.MessageDriven;
      //import javax.interceptor.Interceptors;
      import javax.jms.Message;
      import javax.jms.MessageListener;
      import javax.jms.TextMessage;
      
      import org.apache.commons.logging.Log;
      import org.apache.commons.logging.LogFactory;
      //import org.springframework.beans.factory.annotation.Autowired;
      //import org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor;
      
      
      /**
       * Message-Driven Bean implementation class for: MessageBeanEJB
       *
       */
      @MessageDriven(activationConfig = {
       @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
       @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/pnr"),
       })
      //@Interceptors(SpringBeanAutowiringInterceptor.class)
      public class MessageBeanEJB implements MessageListener {
      
       //@Autowired
       //private PnrProcessor pnrProcessor;
      
       private final Log log = LogFactory.getLog(MessageBeanEJB.class);
      
       /**
       * Default constructor.
       */
       public MessageBeanEJB() {
       // TODO Auto-generated constructor stub
       }
      
       /**
       * @see MessageListener#onMessage(Message)
       */
       public void onMessage(Message message) {
       TextMessage msg = null;
      
       try {
       if (message instanceof TextMessage) {
       msg = (TextMessage) message;
       String data = msg.getText();
      
       log.info(String.format("Received message %s", data));
       //pnrProcessor.process(data);
      
       } else {
       log.error(String.format("Invalid message type %s received. Expecting text message ",message.getClass().getName()));
       }
       } catch (Throwable te) {
       log.error("unable to process message",te);
       RuntimeException ex = new RuntimeException("Unable to process message");
       ex.initCause(te);
       throw ex;
       }
      
       }
      
      }
      


      on my jboss.xml I have this:

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS 5.0//EN" "http://www.jboss.org/j2ee/dtd/jboss_5_0.dtd">
      
      <jboss>
       <enterprise-beans>
       <message-driven>
      
       <ejb-name>MessageBeanEJB</ejb-name>
       <resource-adapter-name>wmq.jmsra.rar</resource-adapter-name>
       </message-driven>
       </enterprise-beans>
      
       <container-configurations>
      
       </container-configurations>
      </jboss>
      


      Note that I am already hardcoding inside the ejb inside jboss.xml that it uses the resource adapter wmq.jmsra.rar. which is undesirable.

      When I deploy it to jboss, this is the result:

      ...
      
      Caused by: com.ibm.msg.client.jms.DetailedIllegalStateException: JMSWMQ0018: Failed to connect to queue manager '' with connection mode 'Client' and host name 'localhost'. Check the queue manager is started and if running in client mode, check there is a listener running. Please see the linked exception for more information.
       at com.ibm.msg.client.wmq.common.internal.Reason.reasonToException(Reason.java:489)
       at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:219)
       at com.ibm.msg.client.wmq.internal.WMQConnection.<init>(WMQConnection.java:410)
       at com.ibm.msg.client.wmq.internal.WMQXAConnection.<init>(WMQXAConnection.java:70)
       at com.ibm.msg.client.wmq.factories.WMQXAConnectionFactory.createV7ProviderConnection(WMQXAConnectionFactory.java:178)
       at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createProviderConnection(WMQConnectionFactory.java:7331)
       at com.ibm.msg.client.wmq.factories.WMQXAConnectionFactory.createProviderXAConnection(WMQXAConnectionFactory.java:101)
       at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl.createXAConnectionInternal(JmsConnectionFactoryImpl.java:332)
       at com.ibm.mq.jms.MQXAConnectionFactory.createXAConnection(MQXAConnectionFactory.java:124)
       at com.ibm.mq.connector.ResourceAdapterConnectionPool.initializeJMSConnection(ResourceAdapterConnectionPool.java:462)
       at com.ibm.mq.connector.ResourceAdapterConnectionPool.createNewConnection(ResourceAdapterConnectionPool.java:376)
       at com.ibm.mq.connector.ResourceAdapterConnectionPool.allocateConnection(ResourceAdapterConnectionPool.java:298)
       ... 60 more
      
      ...
      



      As you can see from the exception, it is not picking up the queue manager name, or the hostname from the connectionFactory. In fact it looks to me that it is not using the configured connectionFactory at all.

      Is there a property that I can set on ejb-jar.xml, jboss.xml, or annotation to tell the ejb to use a specific connectionFactory from jndi?

      I have searched all over the web and have been unable to find a way to associate the connectionFactory with the MDB. I have not found any way to get the queue configuration out of the ejb, I would like to have it out of the ejb-jar.xml, out of jboss.xml, and out of the java code, and into a config file in the AS.

      My apologies if this has been asked before, but I have been searching for 2 days, and have been unable to come up with an answer or get it to work.

      Please help.

      Thanks.