Essex Boy
Essex Boy

Reputation: 7950

Cannot convert value of type [com.ibm.ejs.jms.JMSQueueConnectionFactoryHandle] to required type [javax.jms.ConnectionFactory]

I have standard Spring JMS config

    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="connectionFactory" />
        <property name="defaultDestination" ref="jmsdestination" />
    </bean>
    <bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="jms/MQAuditQueueConnectionFactory" />
    </bean>
    <bean id="jmsDestinationResolver" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="jms/MQAuditQueue" />
    </bean>

And I think a standard MQ on WAS 8.5.5.2, when I start my web-app I get:

 Cannot convert value of type [com.ibm.ejs.jms.JMSQueueConnectionFactoryHandle] to required type [javax.jms.ConnectionFactory] for property 'connectionFactory'

I note from my server I have the following classes in the following jars

class  com/ibm/ejs/jms/JMSQueueConnectionFactoryHandle.class found in /opt/websphere/was8//plugins/com.ibm.ws.runtime.jar

and

com/ibm/mq/jms/MQQueueConnectionFactory.class found in /opt/websphere/was8//installedConnectors/wmq.jmsra.rar/com.ibm.mqjms.jar

How do I get the WAS MQ to use the 2nd jar?

Upvotes: 2

Views: 4816

Answers (3)

Migueles
Migueles

Reputation: 26

I just change this:

<!-- Spring JMS Queue Connection Factory -->
    <bean id="jmsQueueConnectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
        <property name="targetConnectionFactory" ref="internalJmsQueueConnectionFactory"/>
    </bean>

    <!-- JMS Queue Connection Factory -->
    <bean id="internalJmsQueueConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiTemplate" ref="jndiTemplate"/>
        <property name="resourceRef" value="false"/>
        <property name="jndiName" value="${jms.jndi.connection.factory}"/>
    </bean>

...for this:

<!-- Spring JMS Queue Connection Factory -->
    <bean id="jmsQueueConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiTemplate" ref="jndiTemplate"/>
        <property name="resourceRef" value="false"/>
        <property name="jndiName" value="${jms.jndi.connection.factory}"/>
    </bean>

...and delete the jms-2.0.jar library from the claspath and it worked in WAS 8.5 with classloader in PARENT_LAST (I'm not using maven).

Upvotes: 0

Essex Boy
Essex Boy

Reputation: 7950

After lots of trial and error I found the answer is to exclude the jms-api which comes with spring-jms, in your pom.xml.

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-jms</artifactId>
  <version>${spring.version}</version>
    <exclusions>
      <exclusion>
        <groupId>javax.jms</groupId>
        <artifactId>javax.jms-api</artifactId>
      </exclusion>
    </exclusions>
</dependency>

Upvotes: 0

anythingcool1
anythingcool1

Reputation: 31

I also went through a lot of trial and error to find the answer. As mentioned above excluding the jms library works. But how do you exclude the jms library and still be able to compile the code? That was something no one seems to have mentioned. The solution to that is to make the scope for the jms library to "provided" (if you are using Maven or Gradle).

As mentioned somewhere:

"Provided means that you need the JAR for compiling, but at run time there is already a JAR provided by the environment so you don't need it packaged with your app. For a web app, this means that the JAR file will not be placed into the WEB-INF/lib directory."

So in your pom.xml add/update these:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jms</artifactId>
    <version>4.3.4.RELEASE</version>
    <exclusions>
        <exclusion>
            <groupId>javax.jms</groupId>
            <artifactId>javax.jms-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>javax.jms</groupId>
    <artifactId>jms</artifactId>
    <version>1.1</version>
    <scope>provided</scope>
</dependency>

Hopefully this can be helpful to those who have been frustrated by the lack of answers from the Internet.

Upvotes: 3

Related Questions