在尝试elastic-job 分布式任务时,跑example代码,任务正常启动。把example迁移到我们自己的应用后,发现无法启动,报错如下:
Exception in thread "main" java.lang.IncompatibleClassChangeError: Implementing class at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(Unknown Source) at java.security.SecureClassLoader.defineClass(Unknown Source) at java.net.URLClassLoader.defineClass(Unknown Source) at java.net.URLClassLoader.access$100(Unknown Source) at java.net.URLClassLoader$1.run(Unknown Source) at java.net.URLClassLoader$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at com.dangdang.ddframe.job.api.JobScheduler.createJobDetail(JobScheduler.java:134) at com.dangdang.ddframe.job.api.JobScheduler.init(JobScheduler.java:113) at test.JobMain.main(JobMain.java:47)
换回1.7后,发现问题依旧。经过一翻搜索,出现该问题的原因基本是由于加载jar重复导致。于是排查新引进的elastic-job 相关jar包的maven 依赖,mvn dependency:tree把依赖打出来,发现新引进来的quartz包有不同版本,于是把quartz旧版本依赖删除后,不幸发现问题依旧。重新排查了一遍maven依赖,发现除了新引进的2.2.1的quartz版本,再没其他依赖进来的quartz版本。纠结。
于是继承排查报错的源码:
com.dangdang.ddframe.job.api.JobScheduler.createJobDetail(JobScheduler.java:134)
其中报错134行代码如下,在执行下面这行代码,debug发现在load class时报错,此时没看到具体load哪个class,但从代码来看是在加载JobDetail和ZJobBuilder类。
JobDetail result = JobBuilder.newJob(jobConfiguration.getJobClass()).withIdentity(jobConfiguration.getJobName()).build();
于时乎用jvisuavm看了下加载的classpath,果然quartz还有两个版本,一个是 quartz 1.5.2 另一个是quartz 2.2.1。好吧。。。
最后发现eclipse java工程 里有依赖了其他工程 ,其他工程里有引进了quartz 1.5.2,至此原因找到了。但奇怪为什么mvn dependency:tree去看时没看到有把quartz依赖进来。
解决:去掉eclipse build上依赖的project。pom里引用加上冲突解决后任务正常启动。
<exclusions> <exclusion> <groupId>quartz</groupId> <artifactId>quartz</artifactId> </exclusion> </exclusions>