Caused by: java.lang.RuntimeException: xxl-job jobhandler[shardingJobHandler] naming conflicts

问题描述

  在对任务调度系统进行更新后,执行器运行不起来,显示:

Caused by: java.lang.RuntimeException: xxl-job jobhandler[shardingJobHandler] naming conflicts.

问题分析

  对抛问题的地方进行追踪,找到代码:

if (loadJobHandler(name) != null) {
   throw new RuntimeException("xxl-job jobhandler[" + name + "] naming conflicts.");
}

  继续跟踪方法loadJobHandler

private static ConcurrentMap jobHandlerRepository = new ConcurrentHashMap();
public static IJobHandler registJobHandler(String name, IJobHandler jobHandler){
    logger.info(">>>>>>>>>>> xxl-job register jobhandler success, name:{}, jobHandler:{}", name, jobHandler);
    return jobHandlerRepository.put(name, jobHandler);
}
public static IJobHandler loadJobHandler(String name){
    return jobHandlerRepository.get(name);
}

  报错是因为jobHandlerRepository中已存在该JobHandler,因此追踪存储该JobHandlerregistJobHandler方法调用。有两个调用,这个是在抛异常的方法后,一个是:

private void initJobHandlerRepository(ApplicationContext applicationContext) {
    if (applicationContext == null) {
        return;
    }
    // init job handler action
    Map serviceBeanMap = applicationContext.getBeansWithAnnotation(JobHandler.class);

    if (serviceBeanMap!=null && serviceBeanMap.size()>0) {
        for (Object serviceBean : serviceBeanMap.values()) {
            if (serviceBean instanceof IJobHandler){
                String name = serviceBean.getClass().getAnnotation(JobHandler.class).value();
                IJobHandler handler = (IJobHandler) serviceBean;
                if (loadJobHandler(name) != null) {
                    throw new RuntimeException("xxl-job jobhandler[" + name + "] naming conflicts.");
                }
                registJobHandler(name, handler);
            }
        }
    }
}

  进行Debug调试,发现serviceBeanMap读取bean对象时,获取了demoJobHandlershardingJobHandlercommandJobHandlerhttpJobHandler。对原版demo进行debug发现此处serviceBeanMapnull

  对Bean对象的创建进行追踪,发现代码完全一致,陷入怀疑人身的状态。

  死马当活马医,察觉到demoJobHandler2这个新增的JobHandler没有被读取,修改其他JobHandler的名称、属性,发现修改后serviceBeanMap读取的依旧是之前的四个对象,其名称依旧不变,终于发现问题所在。

问题解决

  由于进行版本迭代,代码改动较大,之前版本生成的class文件未删除,在新版本执行时,读取的Bean对象是之前生成的,因此这里无论怎么改对象名称读取的依旧是之前的对象。解决问题的办法很简单,在项目的根目录下执行:

mvn clean

  然后重启项目,问题解决。反思一下,自己对于SpringBootBean对象创建、读取还不是很了解,导致解决这种问题有点像无头苍蝇,需要对这方面进一步深入学习。

你可能感兴趣的:(xxl-job)