Tomcat8 和 ActiveMQ:名为 'someQueue' 的 Bean 必须是 [javax.jms.Queue] 类型,但实际上是 [org.apache.activemq.command.ActiveMQQueue] 类型
Tomcat8 and ActiveMQ: Bean named 'someQueue' must be of type [javax.jms.Queue], but was actually of type [org.apache.activemq.command.ActiveMQQueue]
我在 Tomcat 8 (8.5.4) 为 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
is effectively of type 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 公开队列是否需要进一步的配置?
你不是在服务器端和客户端声明了两种不同的类型吗?
//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 然后你收到一些实现它的东西 -> downcasting
应该相反或者服务器类型设置为queue
问题已解决:这是一个 类路径问题。
应用与问题中报告的完全相同的配置,并通过简单地从部署的 war
中删除 javax.jms-api
库,不再有例外。
以下内容应用于应用程序的 pom.xml
文件(实际上应用于其 war 模块):
<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
库所需的相同。
此冲突是由于 activemq-all-5.14.0.jar
在 Tomcat lib
文件夹中的使用,这也带来了 javax.jms-api
库,因此也在运行时作为应用程序类路径的一部分出现。将应用程序依赖性更改为范围 provided
它将它从最终的 war
文件中删除,因此避免了部署和应用程序启动时间的冲突。
我在 Tomcat 8 (8.5.4) 为 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
is effectively of type 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 公开队列是否需要进一步的配置?
你不是在服务器端和客户端声明了两种不同的类型吗?
//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 然后你收到一些实现它的东西 -> downcasting
应该相反或者服务器类型设置为queue
问题已解决:这是一个 类路径问题。
应用与问题中报告的完全相同的配置,并通过简单地从部署的 war
中删除 javax.jms-api
库,不再有例外。
以下内容应用于应用程序的 pom.xml
文件(实际上应用于其 war 模块):
<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
库所需的相同。
此冲突是由于 activemq-all-5.14.0.jar
在 Tomcat lib
文件夹中的使用,这也带来了 javax.jms-api
库,因此也在运行时作为应用程序类路径的一部分出现。将应用程序依赖性更改为范围 provided
它将它从最终的 war
文件中删除,因此避免了部署和应用程序启动时间的冲突。