Tomcat8和ActiveMQ:Bean命名为“someQueue'必须是[javax.jms.Queue]类型,但实际上是[org.apache.activemq.command.ActiveMQQueue]类型

时间:2016-08-24 15:19:07

标签: java spring tomcat activemq tomcat8

我在Tomcat 8( 8.5.4 )上配置ActiveMQ( 5.14.0 )时会遇到famous BeanNotOfRequiredTypeException异常Spring( 3.2.8 )应用程序的JMS队列。

several提出的修正类似问题(更改AOP和代理行为)没有帮助:应用更改后,再次出现同样的错误:

  

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'notificationService': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'someQueue' must be of type [javax.jms.Queue], but was actually of type [org.apache.activemq.command.ActiveMQQueue]

即使ActiveMQQueue实际上属于Queue类型。

当前配置:

Spring应用程序通过JNDI查找队列:

<jee:jndi-lookup jndi-name="jms/someQueue" id="someQueue" />

web.xml文件中引用了队列:

<resource-ref>
    <description>Factory</description>
    <res-ref-name>jms/someConnectionFactory</res-ref-name>
    <res-type>javax.jms.QueueConnectionFactory</res-type>
    <res-auth>Container</res-auth>
</resource-ref>

<resource-ref>
    <description>Queue</description>
    <res-ref-name>jms/someProcessQueue</res-ref-name>
    <res-type>javax.jms.Queue</res-type>
    <res-auth>Container</res-auth>
</resource-ref>

在服务器端,队列在Tomcat server.xml文件中配置为GlobalNamingResources

<Resource name="jms/someConnectionFactory" 
        auth="Container" 
        type="org.apache.activemq.ActiveMQConnectionFactory" 
        factory="org.apache.activemq.jndi.JNDIReferenceFactory" 
        description="JMS Connection Factory" 
        brokerURL="vm://localhost" 
        brokerName="LocalActiveMQBroker" 
        useEmbeddedBroker="true"
    />

<Resource name="jms/someQueue"
        auth="Container"
        type="org.apache.activemq.command.ActiveMQQueue"
        description="JMS queue"
        factory="org.apache.activemq.jndi.JNDIReferenceFactory"
        physicalName="SOME.QUEUE"
    />  

到目前为止应用的最小配置。对数据源和邮件服务(server.xml + web.xml + JNDI)采用了相同的方法,但是队列配置失败了。

问题:为什么Spring一直认为它是错误的类型?是否需要在Tomcat 8上设置ActiveMQ并通过JNDI公开队列进一步配置?

2 个答案:

答案 0 :(得分:0)

您是否在服务器端和客户端声明了两种不同的类型?

//On the Tomcat side
type="org.apache.activemq.command.ActiveMQQueue"

//In the web.xml of your app
<res-type>javax.jms.Queue</res-type>

为了更好地解释:你在这里向下转发:你在你的应用程序web.xml中声明了一个队列接口类型,并且你收到了一些实现它的东西 - &gt; downcasting
它应该相反或将服务器类型设置为队列

答案 1 :(得分:0)

问题解决了:这是类路径问题

使用与问题中报告的完全相同的配置,只需从已部署的javax.jms-api中移除war库,就不再有例外了。

以下内容适用于应用程序的pom.xml文件(实际上是其战争模块):

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>javax.jms</groupId>
            <artifactId>javax.jms-api</artifactId>
            <version>2.0.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

注意:javax.mail-api库所需的内容相同。

这种冲突是由于在Tomcat activemq-all-5.14.0.jar文件夹中使用了lib,这也带来了javax.jms-api库,因此也是应用程序的一部分运行时的classpath。将应用程序依赖项更改为范围provided,它将其从最终的war文件中删除,从而避免了部署和应用程序启动时间的冲突。