我已经调试了一段时间,我希望有人可以在这里阐明一些信息。
我有一个使用JDK 1.6添加到Jenkins中的Maven项目。我在这个项目中使用AOP来处理数据库事务。
当我在Jenkins中运行构建时,我的测试用例由于以下异常而失败:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataHandlerClassificationImpl': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'writerDataLocationImpl' must be of type [xxx.script.WriterData], but was actually of type [$Proxy17] ... ... Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'writerDataLocationImpl' must be of type [xxx.script.WriterData], but was actually of type [$Proxy17] ... ...
本DataHandlerClassificationImpl类看起来是这样的:
DataHandlerClassificationImpl
@Service public class DataHandlerClassificationImpl extends DataHandler { @Resource(name="writerDataLocationImpl") private WriterData writerData; ... }
WriterData 是具有多种实现的接口。
WriterData
我可以从IDE中执行代码而不会出现问题。为了确定是Maven问题还是Jenkins问题,我使用命令行导航到Jenkins的项目作业文件夹,并且能够mvn test无任何错误地运行。
我知道代理错误与AOP有关,并且我只能自动连接到接口,而不是具体的类……但是这里不是这种情况,因为我可以在Jenkins外部很好地运行代码。
谢谢。
摘自上面的问题评论:
你是否在Jenkins上运行Cobertura,Sonar或其他代码工具?请注意,mvn site也可能配置为在generate中包含Cobertura报告site。
mvn site
site
Cobertura的问题在于它执行相当繁重的字节码检测,包括添加一些自定义接口。当Spring启动时,它将为bean生成代理。如果bean具有至少一个接口,则它将使用标准Java代理。否则,它将尝试创建基于类的代理。
我猜在你的情况下,使用了CGLIB类代理,但是在Cobertura工具spring之后又回到了Java代理。这导致启动错误,因为依赖项注入期望类(或CGLIB子类)。
简而言之,强制使用CGLIB类代理,你会没事的:
<aop:config proxy-target-class="true"/>