替换JMS ConnectionFactory为ActiveMQ类型匹配却触发运行错误
问题:ActiveMQ依赖替换后JNDI资源类型匹配异常
将activemq-all 5.18.6替换为activemq-broker和activemq-client后,已将所有Java Servlet XML配置及代码中的javax.jms.ConnectionFactory替换为org.apache.activemq.ActiveMQConnectionFactory,且确认无拼写错误,但运行时Catalina日志抛出以下异常:
WARNING [main] XmlWebApplicationContext.refresh Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'JMSConnectionFactory' defined in ServletContext resoure [/WEB-INF/JmsProcessing-servlet.xml]: Invocation of init method failed; nested exception is javax.naming.NamingException: Unexpected exception resolving reference [Root exception is java.lang.IllegalArgumentException: The local resource link [ConnectionFactory] that refers to global resource [jms/ConnectionFactory] was expected to return an instance of [org.apache.activemq.ActiveMQConnectionFactory] but returned an instance of [org.apache.activemq.ActiveMQConnectionFactory]]
相关配置文件
context.xml
<?xml....?> <Context docBase="JmsProcessing" reloadable="true"> <ResourceLink name="jdbc/dev" global="jdbc/dev" type="javax.sql.DataSource" /> <ResourceLink name="jms/ConnectionFactory" global="jms/ConnectionFactory" type="org.apache.activemq.ActiveMQConnectionFactory" /> <!-- was type="javax.jms.ConnectionFactory" --> </Context>
JmsProcessing-servlet.xml
<?xml ... ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd org/springframework/beans/factory/xml/spring-beans-2.5.xsd spring-beans-2.5.xsd"> <bean id="JMSConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"> <value>java:comp/env/jms/ConnectionFactory</value> </property> </bean> <bean name="processingBean" class="com.custom.processing.impl.JmsProcessor"> <property name="connectionFactory" ref="JMSConnectionFactory" /> </bean> </beans>
环境信息
- Spring版本:4.3.18
- 构建JDK:17
- 运行JDK:11
- 运行环境:RH9
- Jar包位置异常:
activemq-client-5.18.6.jar同时存在于两个目录:tomcat/lib/activemq-client-5.18.6.jartomcat/webapps/JmsProcessing/WEB-INF/lib/activemq-client-5.18.6.jar
解决方法
1. 消除Jar包类加载冲突
异常提示中看似矛盾的“期望类型与返回类型相同”,本质是类加载器不一致导致的类型不匹配:Tomcat的lib目录由Common类加载器加载,Web应用的WEB-INF/lib由WebApp类加载器加载,同一类被两个不同类加载器加载后会被视为不同类型。
解决步骤:
- 删除
tomcat/webapps/JmsProcessing/WEB-INF/lib/下的activemq-client-5.18.6.jar,保留tomcat/lib/下的Jar包; - 或反之,删除
tomcat/lib/下的Jar包,仅保留Web应用内部的Jar包。- 推荐优先保留Web应用内部的Jar包,避免影响其他Web应用,同时确保
activemq-broker相关依赖也仅存在于Web应用的WEB-INF/lib中。
- 推荐优先保留Web应用内部的Jar包,避免影响其他Web应用,同时确保
2. 检查全局JNDI资源配置
确认Tomcat全局配置(如server.xml或conf/context.xml)中jms/ConnectionFactory的type属性是否已同步改为org.apache.activemq.ActiveMQConnectionFactory:
- 若全局资源仍使用
javax.jms.ConnectionFactory,即便ResourceLink指定了具体实现类,也会导致类型不匹配。
3. 优化Spring JNDI配置
在JmsProcessing-servlet.xml的JMSConnectionFactory bean中显式指定expectedType,确保Spring正确转换类型:
<bean id="JMSConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="java:comp/env/jms/ConnectionFactory" /> <property name="expectedType" value="org.apache.activemq.ActiveMQConnectionFactory" /> </bean>
内容的提问来源于stack exchange,提问作者Codes with Hammer
相关产品推荐
相关产品推荐

