Trying out XA, part 3: dead ends

In our last episode, we got our little .war file to deploy to JBoss with the JtaTransactionManager bean and QueueConnectionFactory defined in the Spring bean file.  Next we need to get the DefaultMessageListenerContainer bean to work.

First let’s try just uncommenting what we have, and see if it Just Works.

Here’s what we get:

13:15:37,740 ERROR [ContextLoader] Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘jmsContainer’ defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type [org.apache.activemq.ra.ActiveMQConnectionFactory] to required type [javax.jms.ConnectionFactory] for property ‘connectionFactory’; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [org.apache.activemq.ra.ActiveMQConnectionFactory] to required type [javax.jms.ConnectionFactory] for property ‘connectionFactory’: no matching editors or conversion strategy found

It looks like the org.apache.activemq.ra.ActiveMQConnectionFactory that the JNDI lookup got us is not a javax.jms.ConnectionFactory.  Assuming we’re on the right track, I wonder how we would get it to be a JMS ConnectionFactory?

A Different Track

I think we’re on the wrong track, though.  Looking in the activemq-jms-ds.xml file, which defines the datasource (if I have my terminology right) for the java:activemq/QueueConnectionFactory JNDI name, I see these tags at the same level:

<jndi-name>activemq/QueueConnectionFactory</jndi-name>

<connection-definition>javax.jms.QueueConnectionFactory</connection-definition>

Now a javax.jms.QueueConnectionFactory is not the same thing as a javax.jms.ConnectionFactory.  Spring’s DefaultMessageListenerContainer wants the javax.jms.ConnectionFactory, not just a QueueConnectionFactory, so I think we need to modify the activemq-jms-ds.xml file to expose a full-fledged ConnectionFactory.  I think when I was digging around in the activemq-ra.rar, I saw a ConnectionFactory sitting around in there… maybe in the meta-inf/ra.xml file?

Exposing a Full-Fledged ConnectionFactory

Let’s try making this change in the activemq-jms-ds.xml file and see what happens:

<tx-connection-factory>
<jndi-name>activemq/FullFledgedConnectionFactory</jndi-name>
<xa-transaction/>
<track-connection-by-tx/>
<rar-name>activemq-ra.rar</rar-name>
<connection-definition>javax.jms.ConnectionFactory</connection-definition>
<ServerUrl>tcp://localhost</ServerUrl>
<min-pool-size>1</min-pool-size>
<max-pool-size>200</max-pool-size>
<blocking-timeout-millis>30000</blocking-timeout-millis>
<idle-timeout-minutes>3</idle-timeout-minutes>
</tx-connection-factory>

For this to work, JBoss would have to be able to find some javax.jms.ConnectionFactory-implementing class in activemq-ra.rar.  It’s no more magic than before, just specifying a different interface than we did before.  The whimsical FullFledged… naming scheme is so it’s easy to notice if the new thing shows up.

Modifying the Spring Bean File Correspondingly

When I deploy the updated datasource configuration file to JBoss, I get a promising-looking message on the JBoss console:

13:42:39,475 INFO  [ConnectionFactoryBindingService] Bound ConnectionManager ‘jboss.jca:service=ConnectionFactoryBinding,name=activemq/FullFledgedConnectionFactory’ to JNDI name ‘java:activemq/FullFledgedConnectionFactory’

So let’s modify the Spring bean file accordingly:

<jee:jndi-lookup id=”connectionFactory” jndi-name=”java:activemq/FullFledgedConnectionFactory”/>

<bean id=”jmsContainer” class=”org.springframework.jms.listener.DefaultMessageListenerContainer”>
<property name=”connectionFactory” ref=”connectionFactory”/>
<property name=”destination” ref=”destination”/>
<property name=”messageListener” ref=”messageListener”/>
<property name=”transactionManager” ref=”transactionManager”/>
</bean>

And…

Not There Yet

When we deploy the .war file, we now get:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘jmsContainer’ defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type [org.apache.activemq.ra.ActiveMQConnectionFactory] to required type [javax.jms.ConnectionFactory] for property ‘connectionFactory’; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [org.apache.activemq.ra.ActiveMQConnectionFactory] to required type [javax.jms.ConnectionFactory] for property ‘connectionFactory’: no matching editors or conversion strategy found

Awwwww!  I really thought we had it this time, but a org.apache.activemq.ra.ActiveMQConnectionFactory is still not a javax.jms.ConnectionFactory.  I think the time has come to take a closer look at this org.apache.activemq.ra package.

Dead End and a New Try

[Time passes…]

I couldn’t find much of anything about this ra package.  Looking in the Spring manual, Section 19.5. Support for JCA Message Endpoints and 19.6. JMS Namespace Support, it looks like I should rename my JNDI bean id to reflect that it is actually (I think) a resource adapter and not a connection factory:

<jee:jndi-lookup id=”resourceAdapter” jndi-name=”java:activemq/FullFledgedConnectionFactory”/>

And then I think I can configure the (JCA-based, now) listener container something like this:

<jms:jca-listener-container resource-adapter="resourceAdapter"
                            transaction-manager="transactionManager">
    <jms:listener destination="destination" ref="messageListener"/>
</jms:jca-listener-container>

Is that still a DefaultMessageListenerContainer?  It’s kind of hard to tell…

Apparently It’s Not a ResourceAdapter Either…

When we deploy with these modifications, we get this error:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘org.springframework.jms.listener.endpoint.JmsMessageEndpointManager#0’: Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type [org.apache.activemq.ra.ActiveMQConnectionFactory] to required type [javax.resource.spi.ResourceAdapter] for property ‘resourceAdapter’; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [org.apache.activemq.ra.ActiveMQConnectionFactory] to required type [javax.resource.spi.ResourceAdapter] for property ‘resourceAdapter’: no matching editors or conversion strategy found

Well, that’s enough for this episode.  In Episode 4 we’ll see if we can break through with a solution.

Advertisements

, , ,

  1. Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s