简介
引入jedis+Spring Data Redis后Quartz类加载器启动异常
流程
1.首先根据Spring版本:4.3.25.RELEASE,maven进了一下依赖:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.8.23.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
2.遇到了以下问题:
[ERROR] org.springframework.web.context.ContextLoader - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'quartzScheduler' defined in class path resource [applicationContext-quartz.xml]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: org.quartz.SchedulerContext.put(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;
3.错误分析:
当引入A导致B出错的可能是依赖错误。紧接着查看spring-data-redis与quartz的依赖:
于是惊奇的发现,quartz-all 1.6没有依赖,但是spring-data-redis的slf4j依赖非常可疑。由于没有排查思路,只能从slf4j入手:将pom直接引用的1.6.1版本的slf4j升级:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.25</version>
</dependency>
4.再次运行,错误如下:
[ERROR] org.springframework.web.context.ContextLoader - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'quartzScheduler' defined in class path resource [applicationContext-quartz.xml]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: org.quartz.SchedulerContext.put(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;
没错,错误一丝变化都没有。于是根据我上了maven仓库查了一下quartz-all:
虽然我不了解quartz,但是这个维护时间我是难以置信的,同时我还发现了这个:
如果我没猜错,quartz一定是quartz-all的后继版本,于是一气之下改成了最新版本(它依赖于slf1.7.x):
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>
然后运行程序,报错显示标签错误,根据
博客指引,终于不再报错,程序正常启动。
疑点
根据maven的最短路径原则,由于本pom中已经存在slf4j且处于生效状态,那么redis-spring引用的slf4版本使用的还是pom中已经存在的slf4j的版本,那么为什么会导致quartz的功能失效?
总而言之,此次问题的解决个人感觉属于歪打正着,欢迎大家一同研究一下问题本质。