{"record":{"id":"277bd8f986aba573","repo":"quarkusio/quarkus","slug":"job-beanclass-can-not-be-interrupted-since-it","errorCode":null,"errorMessage":"Job ${beanClass} can not be interrupted, since it does not implement org.quartz.InterruptableJob","messagePattern":"Job (.+?) can not be interrupted, since it does not implement org\\.quartz\\.InterruptableJob","errorType":"exception","errorClass":"UnableToInterruptJobException","httpStatus":null,"severity":"error","filePath":"extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/CdiAwareJob.java","lineNumber":51,"sourceCode":"        try {\n            beanInstance.execute(context);\n        } catch (JobExecutionException e) {\n            refire = e.refireImmediately();\n            throw e;\n        } finally {\n            if (refire != true && handle.getBean().getScope().equals(Dependent.class)) {\n                handle.destroy();\n            }\n        }\n    }\n\n    @Override\n    public void interrupt() throws UnableToInterruptJobException {\n        // delegate if possible; throw an exception in other cases\n        if (InterruptableJob.class.isAssignableFrom(handle.getBean().getBeanClass())) {\n            ((InterruptableJob) beanInstance).interrupt();\n        } else {\n            throw new UnableToInterruptJobException(\"Job \" + handle.getBean().getBeanClass()\n                    + \" can not be interrupted, since it does not implement \" + InterruptableJob.class.getName());\n        }\n    }\n}\n","sourceCodeStart":33,"sourceCodeEnd":56,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/CdiAwareJob.java#L33-L56","documentation":"CdiAwareJob wraps CDI-managed @Scheduled job beans. Its interrupt() delegates to the job only if the bean class implements org.quartz.InterruptableJob; otherwise it throws UnableToInterruptJobException with this message. Quartz invokes interrupt() when a job is interrupted via scheduler.interrupt(jobKey) or on scheduler shutdown with interruption requested.","triggerScenarios":"Call scheduler.interrupt(jobKey) (or trigger shutdown-with-interrupt) for a @Scheduled CDI job bean whose class does not implement InterruptableJob.","commonSituations":"Attempting to cancel long-running scheduled methods programmatically; stopping the app while a long job runs; assuming all Quartz jobs are interruptible.","solutions":["Make the job bean implement org.quartz.InterruptableJob and handle interruption in interrupt().","Redesign the job to check a cancellation flag/thread interruption instead of relying on Quartz interrupt.","Catch UnableToInterruptJobException at the interrupt call site and handle non-interruptible jobs gracefully."],"exampleFix":"// before\n@Scheduled(cron = \"0 0 * * * ?\")\npublic class ReportJob { public void run() { ... } }\n\n// after\n@Scheduled(cron = \"0 0 * * * ?\")\npublic class ReportJob implements org.quartz.InterruptableJob {\n    public void execute(JobExecutionContext ctx) { while (!Thread.currentThread().isInterrupted()) { ... } }\n    public void interrupt() { Thread.currentThread().interrupt(); }\n}","handlingStrategy":"type-guard","validationCode":"// check before requesting interruption\nClass<?> beanClass = jobHandle.getBean().getBeanClass();\nboolean interruptible = org.quartz.InterruptableJob.class.isAssignableFrom(beanClass);","typeGuard":"static boolean isInterruptableJob(Class<?> beanClass) {\n    return beanClass != null && org.quartz.InterruptableJob.class.isAssignableFrom(beanClass);\n}","tryCatchPattern":"try {\n    scheduler.interrupt(jobKey);\n} catch (org.quartz.UnableToInterruptJobException e) {\n    // job does not implement InterruptableJob: stop it another way\n    log.warn(\"Job not interruptible: \" + jobKey);\n} catch (org.quartz.SchedulerException e) {\n    log.error(\"Failed to interrupt job\", e);\n}","preventionTips":["Implement InterruptableJob on any long-running @Scheduled bean you may need to cancel.","Use a volatile cancellation flag checked inside the job loop.","Document which jobs are interruptible when exposing admin stop endpoints."],"tags":["quarkus","quartz","scheduling","cdi","interruption"],"backgroundTag":"job-not-interruptible","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}