{"record":{"id":"2b1865187bae5bd1","repo":"xuxueli/xxl-job","slug":"xxl-job-method-jobhandler-destroymethod-invalid-f","errorCode":null,"errorMessage":"xxl-job method-jobhandler destroyMethod invalid, for[{}#{}] .","messagePattern":"xxl-job method-jobhandler destroyMethod invalid, for\\[(.+?)#(.+?)\\] \\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"xxl-job-core/src/main/java/com/xxl/job/core/executor/XxlJobExecutor.java","lineNumber":376,"sourceCode":"\n        // init and destroy\n        Method initMethod = null;\n        Method destroyMethod = null;\n\n        if (StringTool.isNotBlank(xxlJob.init())) {\n            try {\n                initMethod = clazz.getDeclaredMethod(xxlJob.init());\n                initMethod.setAccessible(true);\n            } catch (NoSuchMethodException e) {\n                throw new RuntimeException(\"xxl-job method-jobhandler initMethod invalid, for[\" + clazz + \"#\" + methodName + \"] .\");\n            }\n        }\n        if (StringTool.isNotBlank(xxlJob.destroy())) {\n            try {\n                destroyMethod = clazz.getDeclaredMethod(xxlJob.destroy());\n                destroyMethod.setAccessible(true);\n            } catch (NoSuchMethodException e) {\n                throw new RuntimeException(\"xxl-job method-jobhandler destroyMethod invalid, for[\" + clazz + \"#\" + methodName + \"] .\");\n            }\n        }\n\n        // registry jobhandler\n        registryJobHandler(name, new MethodJobHandler(bean, executeMethod, initMethod, destroyMethod));\n\n    }\n\n\n    // ---------------------- job thread repository ----------------------\n\n    private final ConcurrentMap<Integer, JobThread> jobThreadRepository = new ConcurrentHashMap<>();\n    public JobThread registJobThread(int jobId, IJobHandler handler, String removeOldReason){\n        JobThread newJobThread = new JobThread(jobId, handler);\n        newJobThread.start();\n        logger.info(\">>>>>>>>>>> xxl-job register JobThread success, jobId:{}, handler:{}\", new Object[]{jobId, handler});\n\n        JobThread oldJobThread = jobThreadRepository.put(jobId, newJobThread);\t// putIfAbsent | oh my god, map's put method return the old value!!!","sourceCodeStart":358,"sourceCodeEnd":394,"githubUrl":"https://github.com/xuxueli/xxl-job/blob/e74c784f68f81fa89cb350913ef15794865d7b12/xxl-job-core/src/main/java/com/xxl/job/core/executor/XxlJobExecutor.java#L358-L394","documentation":"Thrown by registryJobHandler when @XxlJob(destroy=\"...\") names a method not found on the bean's class (NoSuchMethodException rewrapped). The destroy lifecycle hook must be a declared no-arg method on the same class.","triggerScenarios":"A handler annotated @XxlJob(value=\"x\", destroy=\"tearDown\") where tearDown is absent, has parameters, sits on a superclass, or was renamed.","commonSituations":"Renamed the cleanup method without updating the annotation; declared it with arguments; method exists only on a parent class invisible to getDeclaredMethod.","solutions":["Declare a no-arg method on the same class matching @XxlJob(destroy=...).","Verify spelling and visibility of the destroy method.","Drop destroy=\"...\" if no teardown is required."],"exampleFix":"// before\n@XxlJob(value=\"x\", destroy=\"cleanup\")\npublic ReturnT<String> execute(String p){...}\n// cleanup() missing\n// after\n@XxlJob(value=\"x\", destroy=\"cleanup\")\npublic ReturnT<String> execute(String p){...}\npublic void cleanup(){ /* release */ }","handlingStrategy":"validation","validationCode":"if (StringTool.isNotBlank(xxlJob.destroy())) {\n    Method dm = clazz.getDeclaredMethod(xxlJob.destroy());\n    if (dm.getParameterCount() != 0) throw new IllegalStateException(\"destroy must be no-arg\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    xxlJobExecutor.start();\n} catch (RuntimeException e) {\n    log.error(\"handler destroy method invalid: {}\", e.getMessage());\n}","preventionTips":["Keep destroy methods no-arg and on the annotated class.","Sync annotation text when renaming cleanup methods.","Reflect-test all @XxlJob init/destroy references at build time."],"tags":["jobhandler","annotation","lifecycle","reflection"],"backgroundTag":null,"analyzedSha":"e74c784f68f81fa89cb350913ef15794865d7b12","analyzedAt":"2026-08-14T04:22:43.715Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}