2 Replies Latest reply on Oct 12, 2012 6:18 AM by sourcedev

    JBoss AS 7 with ActiveMQ Resource Adapter - TransportFactory ClasscastException

    sourcedev

      Hi,

       

      I have JBoss 7.1.2 (EAP 6.0.0.GA) running with the standalone profile against ActiveMQ 5.6, which runs as an external broker on localhost. 

       

      My application attempts to connect to the ActiveMQ broker to publish a message using a spring JmsTemplate.  When the ActiveMQConnectionFactory is instructed to create a connection by the ActiveMQManagedConnectionFactory, I see a class cast error when it attempts to cast the newly created TcpTransportFactory to a TransportFactory.  The error is nicely swallowed up so without debugging, it looks like this:

       

      Caused by: javax.jms.JMSException: IJ000453: Unable to get managed connection for java:jboss/eis/Connection
          at org.apache.activemq.ra.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:101)
          at org.apache.activemq.ra.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:67)
          at org.springframework.jms.support.JmsAccessor.createConnection(JmsAccessor.java:184) [org.springframework.jms-3.1.2.RELEASE.jar:3.1.2.RELEASE]
      

       

      Debugging reveals the real error deep in the ActiveMQ core:

       

      org.apache.activemq.transport.tcp.TcpTransportFactory cannot be cast to org.apache.activemq.transport.TransportFactory
      

       

      I am guessing this is because the two classes are loaded by different classloaders rather than it being caused by the resource adapter set-up.  The classes exist in the activemq-core.5.6.0.jar, which exists in two places - the application's ear->war->WEB-INF/lib folder and the Active MQ rar folder under standalone/deployments. 

       

      I have provisioned the ActiveMQ resource adapter as indicated by numerous threads and this seems to start and bind the connection factories correctly to the JNDI names provided.  To provision the adapter, I did the following:

      • Added ra.xml file (attached) in META-INF folder of expanded activemq rar file
      • Added resource-adapters to standalone.xml (see below)

       

      <subsystem xmlns="urn:jboss:domain:resource-adapters:1.0">
          <resource-adapters>
              <resource-adapter>
                  <archive>activemq-rar-5.6.0.rar</archive>
                  <transaction-support>XATransaction</transaction-support>
                  <config-property name="ServerUrl">tcp://localhost:61616</config-property>
                  <connection-definitions>
                      <connection-definition class-name="org.apache.activemq.ra.ActiveMQManagedConnectionFactory" jndi-name="java:jboss/eis/Connection" enabled="true" use-java-context="true" pool-name="Connection" use-ccm="true">
                          <xa-pool>
                              <min-pool-size>1</min-pool-size>
                              <max-pool-size>10</max-pool-size>
                              <prefill>true</prefill>
                              <use-strict-min>true</use-strict-min>
                              <flush-strategy>FailingConnectionOnly</flush-strategy>
                              <pad-xid>false</pad-xid>
                              <wrap-xa-resource>true</wrap-xa-resource>
                          </xa-pool>
                          <security><application/></security>
                      </connection-definition>
                  </connection-definitions>
                  <admin-objects>
                      <admin-object class-name="org.apache.activemq.command.ActiveMQQueue" jndi-name="java:jboss/eis/ao/ActiveMQQueue" enabled="true" use-java-context="true" pool-name="ActiveMQQueue">
                          <config-property name="PhysicalName">testQueue1</config-property>
                      </admin-object>
                      <admin-object class-name="org.apache.activemq.command.ActiveMQTopic" jndi-name="java:jboss/eis/ao/ActiveMQTopic" enabled="true" use-java-context="true" pool-name="ActiveMQTopic">
                          <config-property name="PhysicalName">testTopic1</config-property>
                      </admin-object>
                  </admin-objects>
              </resource-adapter>
          </resource-adapters>
      </subsystem>
      

       

      The application itself has a jboss-deployment-structure.xml file in the ear/META-INF folder.  No idea if this has some effect.

       

      <?xml version="1.0" encoding="UTF-8"?>
      <jboss-deployment-structure> 
        <deployment> 
          <dependencies> 
            <module name="com.mycode" export="true" /> 
            <module name="org.jboss.as.naming" export="true" />
          </dependencies>
        </deployment> 
      </jboss-deployment-structure>
      

       

      Anyone else seen this problem?

       

      Many thanks,

       

      Alex

        • 1. Re: JBoss AS 7 with ActiveMQ Resource Adapter - TransportFactory ClasscastException
          sourcedev

          Just confirmed the issue is classloader-based:

           

          TcpTransportFactory classloader:

          ModuleClassLoader for Module "deployment.5.0.0.72-dataextract.ear.dataextract.war:main" from Service Module Loader

           

          TransportFactory classloader:

          ModuleClassLoader for Module "deployment.activemq-rar-5.6.0.rar:main" from Service Module Loader

           

          Any ideas how to address this?  Is there a way to tell the application to prefer the server classloader?  Alternatively I guess it should be possible to remove the active-mq core jar from the war and instruct the app to load its required MQ classes from the jar under the resource adapter rar at start-up?  The app needs access to classes that are in the core jar like org.apache.activemq.command.ActiveMQQueue. 

           

          Thanks.

          • 2. Re: JBoss AS 7 with ActiveMQ Resource Adapter - TransportFactory ClasscastException
            sourcedev

            OK, so I fixed this by adding the rar reference to the jboss-deployment-structure (based on my previous comment above) and removing the mq core jar from the application:

             

            <?xml version="1.0" encoding="UTF-8"?>

            <jboss-deployment-structure>

              <deployment>

                <dependencies>

                  ...

                  <module name="deployment.activemq-rar-5.6.0.rar" export="true" />

                </dependencies>

              </deployment>

            </jboss-deployment-structure>

             

            Is this the expected way to resolve this? Surprised no-one else mentioned this in the 'how to integrate ActiveMQ with AS7".  Perhaps it's because I'm not using MDBs and most posts were around that - presume the dependency for MDBs is defined elsewhere.

             

            If this is the expected way to do it, hope this is of some use to someone.

             

            Cheers,

             

            Alex