{"record":{"id":"554e7d8e3c96f637","repo":"quarkusio/quarkus","slug":"s-does-not-implement-s","errorCode":null,"errorMessage":"%s does not implement %s","messagePattern":"(.+?) does not implement (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/quartz/deployment/src/main/java/io/quarkus/quartz/deployment/QuartzProcessor.java","lineNumber":383,"sourceCode":"            if (m.getMethod().hasAnnotation(NONCONCURRENT)) {\n                nonconcurrentMethods.add(m.getMethod().declaringClass().name() + \"#\" + m.getMethod().name());\n            }\n        }\n\n        syntheticBeanBuildItemBuildProducer.produce(SyntheticBeanBuildItem.configure(QuartzSupport.class)\n                .scope(Singleton.class) // this should be @ApplicationScoped but it fails for some reason\n                .setRuntimeInit()\n                .supplier(recorder.quartzSupportSupplier(driverDialect.getDriver(), driverDialect.getDataSources(),\n                        nonconcurrentMethods))\n                .done());\n    }\n\n    private static void checkExtensionPoints(Map<String, QuartzExtensionPointConfig> config, Class<?> clazz) {\n        for (QuartzExtensionPointConfig extensionPointConfig : config.values()) {\n            try {\n                if (!clazz.isAssignableFrom(\n                        Class.forName(extensionPointConfig.clazz(), false, Thread.currentThread().getContextClassLoader()))) {\n                    throw new IllegalArgumentException(\n                            String.format(\"%s does not implement %s\", extensionPointConfig.clazz(), clazz));\n                }\n            } catch (ClassNotFoundException e) {\n                throw new IllegalArgumentException(e);\n            }\n        }\n    }\n}\n","sourceCodeStart":365,"sourceCodeEnd":392,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/quartz/deployment/src/main/java/io/quarkus/quartz/deployment/QuartzProcessor.java#L365-L392","documentation":"checkExtensionPoints validates each configured Quartz extension point (JobListener, TriggerListener, etc.) by loading its class and checking that it is assignable from the required interface/parent class. If the class exists but does not implement the required type, an IllegalArgumentException stating '<class> does not implement <type>' is thrown at build time.","triggerScenarios":"Configure a class under quarkus.quartz.<extension-point> (e.g. job-listeners, store-classes) whose class loads successfully but does not extend/implement the required Quartz SPI type, e.g. a listener class that doesn't implement JobListener.","commonSituations":"Pointing a listener config at a plain class or wrong listener type (JobListener vs TriggerListener confusion); implementing the wrong interface after a refactor; copying config between properties of different extension point kinds.","solutions":["Make the configured class implement/extend the required Quartz SPI type (e.g. org.quartz.JobListener).","Check you put the class under the correct config section for its actual type.","Verify against the Quartz API for the version on the classpath — interface names may differ across versions."],"exampleFix":"// before\npublic class MyListener { /* no interface */ }\n\n// after\npublic class MyListener implements org.quartz.JobListener { ... }","handlingStrategy":"validation","validationCode":"// before referencing in config, verify the SPI contract\nClass<?> c = Class.forName(\"com.myapp.MyListener\", false,\n        Thread.currentThread().getContextClassLoader());\nif (!org.quartz.JobListener.class.isAssignableFrom(c)) {\n    throw new IllegalStateException(\"configured listener must implement org.quartz.JobListener\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always implement the exact Quartz SPI interface matching the config section (JobListener vs TriggerListener).","Double-check the config property section before pasting shared listener config.","Add an application-level unit test asserting isAssignableFrom for all configured extension-point classes."],"tags":["quarkus","quartz","build-time","type-mismatch","spi"],"backgroundTag":"class-does-not-implement-interface","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}