SSMP整合ActiveMQ,导致项目启动失败,原因可能如下!
原项目基本环境:
- Spring 4.1.3.RELEAS
- SpringMVC 4.1.3.RELEAS
- Mybatis-Plus 3.4.1
- Maven 3.8.6
- Zookeeper 3.4.7
- Dubbo 2.5.3
项目工程结构
问题描述:
原来在项目加入ActiveMQ之前,已经使用Dubbo,Redis,并且admin端和user端已经能够相互调用,但是加入ActiveMQ与ActiveMQ的连接池,并且通过xml文件配置好spring与ActiveMQ整合后,启动项目直接报错!不管是作为服务提供方的admin还是服务调用方的user都报如下错误!以致于项目启动失败!
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'houseService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could no
t autowire field: private org.springframework.jms.core.JmsTemplate com.codingpang.admin.service.impl.HouseServiceImpl.jmsTemplate; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with
name 'jmsTemplate' defined in class path resource [spring/applicationContext-jms.xml]: Cannot resolve reference to bean 'singleConnectionFactory' while setting bean property 'connectionFactory'; nested exception is org.springframew
ork.beans.factory.BeanCreationException: Error creating bean with name 'singleConnectionFactory' defined in class path resource [spring/applicationContext-jms.xml]: Cannot resolve reference to bean 'connectionFactory' while setting
bean property 'targetConnectionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'connectionFactory' defined in class path resource [spring/applicationContext-jms.xm
l]: Initialization of bean failed; nested exception is java.lang.reflect.MalformedParameterizedTypeException
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at
。。。。 此处省略三千字。。。。
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.jms.core.JmsTemplate com.codingpang.admin.service.impl.HouseServiceImpl.jmsTemplate; nested exception is org.s
pringframework.beans.factory.BeanCreationException: Error creating bean with name 'jmsTemplate' defined in class path resource [spring/applicationContext-jms.xml]: Cannot resolve reference to bean 'singleConnectionFactory' while set
ting bean property 'connectionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'singleConnectionFactory' defined in class path resource [spring/applicationContext-j
ms.xml]: Cannot resolve reference to bean 'connectionFactory' while setting bean property 'targetConnectionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'connectionFactory' defined in class path resource [spring/applicationContext-jms.xml]: Initialization of bean failed; nested exception is java.lang.reflect.MalformedParameterizedTypeException
at
。。。。 此处省略三千字。。。。
... 67 more
异常分析:
考虑到我是一名强迫症,我从上往下去阅读了一下异常,上面的异常是我先从上百行异常信息中从上往下提取出的关键信息,我们来分析下:
首先找到第一个Caused by:
,异常分析开始:
org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.jms.core.JmsTemplate com.codingpang.admin.service.impl.HouseServiceImpl.jmsTemplate;
1.第一句异常:不能在com.codingpang.admin.service.impl.HouseServiceImpl
这个类中将org.springframework.jms.core.JmsTemplate
这个对象注入到com.codingpang.admin.service.impl.HouseServiceImpl.jmsTemplate
属性;
下图可以看出我在HouseServiceImpl
中的确在注入JmsTemplate
对象
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jmsTemplate' defined in class path resource [spring/applicationContext-jms.xml]: Cannot resolve reference to bean 'singleConnectionFactory' while setting bean property 'connectionFactory';
2 第二句异常:在类路径下的spring类路径下的applicationContext-jms.xml文件中创建名为jmsTemplate的bean错误,(原因是:)在设置bean属性值的时候,不能将 'connectionFactory’引用到名为’singleConnectionFactory’的bean,我们顺着这句异常,看看我的配置文件applicationContext-jms.xml:
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'connectionFactory' defined in class path resource [spring/applicationContext-jms.xml]: Initialization of bean failed; nested exception is java.lang.reflect.MalformedParameterizedTypeException
- 上述异常翻译过来意思是:名为connectionFactory的bean 初始化失败;嵌套异常是 java.lang.reflect.MalformedParameterizedTypeException
解决思路
- 既然异常发生的源头是在我们的配置文件,spring整合ActiveMQ使用的是ActiveMQ的连接池注入的,那么证明连接池可能有问题,那么我们注释掉连接池,改用直接使用ActiveMQ的原厂家工厂引用到Spring的SingleConnectionFactory,看看是否能让项目启动成功!
- 那么另外一种解决思路是:既然IDEA已经为我们提示了是mq的连接池问题,那么我下意识地应该去看看我引入的maven jar包是否不能与当前的Spring兼容,若不兼容,我替换jar尝试能否成功运行项目即可。
那么针对上述两种解决思路,我做了下面的两种方式验证,并且都取得了成功!
验证思路与解决结果:
验证思路一:注释掉mq的连接池配置,让Spring直接使用ActiveMQ的原厂家工厂bean完成整合
下图是核心操作:
- 注释掉mq的连接池相关的配置
- 将mq的工厂(原厂家工厂)的bean放到下图的对应位置
- 运行,执行结果无异常,项目成功启动
验证思路二:直接更改ActiveMQ与ActiveMQ连接池的maven驱动版本,看看是否是因为驱动版本的原因造成了Spring无法管理,以至于项目启动失败
- 配置文件不动
- 来到最顶层的pom.xml配置文件,找到ActiveMQ与ActiveMQ连接池的版本进行替换,并刷新maven到项目,经过作者多次测试,ActiveMQ-5.8.0与当前的Spring4.1.3.RELEAS 的确不兼容,按照下图操作进行操作后,使用我参考我贴出来maven配置可能解决(因为作者现在使用的Spring版本可能会和读者的不同,所以大家只能作为参考)
<!--activemq-->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.10.0</version>
</dependency>
<!--activemq连接池-->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>5.15.8</version>
</dependency>
- 运行项目(作者这里是聚合工程,采用maven命令与jetty插件配合重新运行项目)
重新打包构建common模块
cd ..\common\
mvn clean install
安装成功后的标识:
进入admin模块,启动项目:
cd ..\admin
mvn jetty:run
- 运行结果,成功!
总结
在父子聚合,中间件繁多的项目中经常会遇到坑,驱动之间不兼容会是常有的事,遇到问题应该先学会看异常,然后分析具体错误!