无法将类型 [com.ibm.ejs.jms.JMSQueueConnectionFactoryHandle] 的值转换为所需类型 [javax.jms.ConnectionFactory]

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

我有标准的 Spring JMS 配置

    <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>

我认为 WAS 8.5.5.2 上的标准 MQ,当我启动我的网络应用程序时,我得到:

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

我从我的服务器上注意到我在以下 jars

中有以下 类
class  com/ibm/ejs/jms/JMSQueueConnectionFactoryHandle.class found in /opt/websphere/was8//plugins/com.ibm.ws.runtime.jar

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

如何让 WAS MQ 使用第二个 jar?

经过大量试验和错误后,我发现答案是排除 spring-jms 附带的 jms-api,在您的 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>

我也经历了很多试错才找到答案。如上所述,不包括 jms 库的作品。但是如何排除 jms 库并仍然能够编译代码呢?那是似乎没有人提及的事情。解决方案是将 jms 库的范围设置为 "provided"(如果您使用的是 Maven 或 Gradle)。

如某处所述:

"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."

所以在你的 pom.xml add/update 这些:

<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>

希望这对那些因缺乏互联网答案而感到沮丧的人有所帮助。

我只是改变这个:

<!-- 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>

...为此:

<!-- 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>

...并从 claspath 中删除 jms-2.0.jar 库,它在 WAS 8.5 中使用 [= 中的类加载器23=](我没有使用 maven)。