4 Replies Latest reply on Jul 16, 2008 6:36 AM by Derick

    Can't replace container configuration for MDB

    Oleg Timoshenko Newbie

      Good day,

      I am writing an EJB3 (MDB) that gets its messages from IBM MQ 6. JBoss version is 4.0.5.
      I have read very carefully http://wiki.jboss.org/wiki/Wiki.jsp?page=IntegrationWithWebSphereMQSeries describing integration of Web Sphere MQ and JBoss. Those examples are written for EJB2 and work fine, but when I try to apply this to EJB3, it seems JBoss ignores my <container-configuration> settings specified in jboss.xml deployment descriptor and uses ones from standardjboss.xml.

      In particular, my JMSProviderAdaptor is not getting picked up and container falls back on the DefaultJMSProvider as specified in standardjboss.xml for MDBs.
      As a result, I get the following exception during MDB activation:

      15:32:29,944 INFO [JmsActivation] Attempting to reconnect org.jboss.resource.adapter.jms.inflow.JmsActivationSpec@130661d(ra=org.jboss.resource.adapter.jms.JmsResourceAdapter@72c950 destination=wsmq/RequestQueue isTopic=false tx=true durable=false reconnect=10 provider=java:/DefaultJMSProvider user=null maxMessages=1 minSession=1 maxSession=15 keepAlive=60000 useDLQ=true DLQHandler=org.jboss.resource.adapter.jms.inflow.dlq.GenericDLQHandler DLQJndiName=queue/DLQ DLQUser=null DLQMaxResent=0)
      15:32:29,944 ERROR [JmsActivation] Unable to reconnect org.jboss.resource.adapter.jms.inflow.JmsActivationSpec@130661d(ra=org.jboss.resource.adapter.jms.JmsResourceAdapter@72c950 destination=wsmq/RequestQueue isTopic=false tx=true durable=false reconnect=10 provider=java:/DefaultJMSProvider user=null maxMessages=1 minSession=1 maxSession=15 keepAlive=60000 useDLQ=true DLQHandler=org.jboss.resource.adapter.jms.inflow.dlq.GenericDLQHandler DLQJndiName=queue/DLQ DLQUser=null DLQMaxResent=0)
      java.lang.ClassCastException: com.ibm.mq.jms.MQQueue cannot be cast to org.jboss.mq.SpyDestination
       at org.jboss.mq.SpyConnectionConsumer.<init>(SpyConnectionConsumer.java:107)
       at org.jboss.mq.SpyConnection.createConnectionConsumer(SpyConnection.java:128)
       at org.jboss.resource.adapter.jms.inflow.JmsServerSessionPool.setupConsumer(JmsServerSessionPool.java:268)
       at org.jboss.resource.adapter.jms.inflow.JmsServerSessionPool.start(JmsServerSessionPool.java:103)
       at org.jboss.resource.adapter.jms.inflow.JmsActivation.setupSessionPool(JmsActivation.java:540)
       at org.jboss.resource.adapter.jms.inflow.JmsActivation.setup(JmsActivation.java:313)
       at org.jboss.resource.adapter.jms.inflow.JmsActivation.handleFailure(JmsActivation.java:250)
       at org.jboss.resource.adapter.jms.inflow.JmsActivation$SetupActivation.run(JmsActivation.java:593)
       at org.jboss.resource.work.WorkWrapper.execute(WorkWrapper.java:204)
       at org.jboss.util.threadpool.BasicTaskWrapper.run(BasicTaskWrapper.java:275)
       at EDU.oswego.cs.dl.util.concurrent.PooledExecutor$Worker.run(PooledExecutor.java:743)
       at java.lang.Thread.run(Thread.java:619)
      


      -------
      What I've done so far:
      1) I bound WebSphere's Admin Objects into JBoss's JNDI namespace using MBeans borrowed from http://wiki.jboss.org/wiki/Wiki.jsp?page=UsingWebSphereMQSeriesWithJBossASPartI.
      In particular, I bound Queue connection factory and a queue with names WSMQQueueConnectionFactory and wsmq/RequestQueue respectively.

      2) Checked using JNDI browser that the above two objects are successfully bound to JBoss's JNDI namespace with implementation classes as follows:
      com.ibm.mq.jms.MQQueueConnectionFactory for factory and
      com.ibm.mq.jms.MQQueue for queue.

      3) Dropped the following file called wsmq-ds.xml into JBOSS/server/default/deploy folder:
      <connection-factories>
       <mbean code="org.jboss.jms.jndi.JMSProviderLoader" name="jboss.mq:service=JMSProviderLoader,name=WSMQJMSProvider">
       <attribute name="ProviderName">WSMQJMSProvider</attribute>
       <attribute name="ProviderAdapterClass">org.jboss.jms.jndi.JNDIProviderAdapter</attribute>
       <attribute name="QueueFactoryRef">WSMQQueueConnectionFactory</attribute>
       <attribute name="TopicFactoryRef">WSMQTopicConnectionFactory</attribute>
       </mbean>
      </connection-factories>


      and confirmed that new JMS Provider was instantiated and bound in JNDI under name "java:/WSMQJMSProvider"

      4) Created the following deployment descriptor META-INF/jboss.xml:
      <!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS 4.0//EN" "http://www.jboss.org/j2ee/dtd/jboss_4_0.dtd">
      <jboss>
      
       <enterprise-beans>
       <message-driven>
       <ejb-name>TPDocMDB</ejb-name>
       <destination-jndi-name>wsmq/RequestQueue</destination-jndi-name>
       <configuration-name>WSMQ Message Driven Bean</configuration-name>
       </message-driven>
       </enterprise-beans>
      
       <!-- The JmsProviderAdapterJNDI must match the ProviderName in SERVER_HOME/deploy/jms/wsmq-ds.xml file. -->
       <invoker-proxy-bindings>
       <invoker-proxy-binding>
       <name>wsmq-message-driven-bean</name>
       <invoker-mbean>default</invoker-mbean>
       <proxy-factory>org.jboss.ejb.plugins.jms.JMSContainerInvoker</proxy-factory>
       <proxy-factory-config>
       <JMSProviderAdapterJNDI>WSMQJMSProvider</JMSProviderAdapterJNDI>
       <ServerSessionPoolFactoryJNDI>StdJMSPool</ServerSessionPoolFactoryJNDI>
       <!-- <CreateJBossMQDestination>true</CreateJBossMQDestination> -->
       <!-- WARN: Don't set this to zero until a bug in the pooled executor is fixed -->
       <MinimumSize>1</MinimumSize>
       <MaximumSize>15</MaximumSize>
       <KeepAliveMillis>30000</KeepAliveMillis>
       <MaxMessages>1</MaxMessages>
       <MDBConfig>
       <ReconnectIntervalSec>10</ReconnectIntervalSec>
       <DLQConfig>
       <DestinationQueue>queue/DLQ</DestinationQueue>
       <MaxTimesRedelivered>3</MaxTimesRedelivered>
       <TimeToLive>0</TimeToLive>
       </DLQConfig>
       </MDBConfig>
       </proxy-factory-config>
       </invoker-proxy-binding>
       </invoker-proxy-bindings>
      
       <!-- container configuration for WSMQ -->
      
       <container-configurations>
       <container-configuration extends="Standard Message Driven Bean">
       <container-name>WSMQ Message Driven Bean</container-name>
       <invoker-proxy-binding-name>wsmq-message-driven-bean</invoker-proxy-binding-name>
       </container-configuration>
       </container-configurations>
      
      
      </jboss>
      


      5) Deployed an MDB with the following annotations at class level:
      @MessageDriven(mappedName = "TPDocMDB", name="TPDocMDB", activationConfig = {
       @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
       @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
       @ActivationConfigProperty(propertyName = "destination", propertyValue = "wsmq/RequestQueue")
       })
      @TransactionManagement(javax.ejb.TransactionManagementType.CONTAINER)
      


      I found a workaround that allows me specify the following annotation:
      @ActivationConfigProperty(propertyName = "providerAdapterJNDI", propertyValue="java:/WSMQJMSProvider"


      but I also need to change a dead letter queue destination and I can't do it with annotations, therefore I HAVE TO use deployment descriptor.

      I will appreciate if you could help me figure out why <container-configurations> from deployment descriptor is not getting picked up.