{"record":{"id":"7e807e4ed6681f66","repo":"quarkusio/quarkus","slug":"failed-to-load-generated-class-s","errorCode":null,"errorMessage":"Failed to load generated class %s","messagePattern":"Failed to load generated class (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"extensions/oidc-client-graphql/runtime/src/main/java/io/quarkus/oidc/client/graphql/runtime/OidcGraphQLClientIntegrationRecorder.java","lineNumber":35,"sourceCode":"        GraphQLClientsConfiguration configs = GraphQLClientsConfiguration.getInstance();\n        configs.getClients().forEach((graphQLClientKey, value) -> {\n            String oidcClient = configKeysToOidcClients.get(graphQLClientKey);\n            if (oidcClient == null) {\n                oidcClient = defaultOidcClientName;\n            }\n            Map<String, Uni<String>> dynamicHeaders = configs.getClient(graphQLClientKey).getDynamicHeaders();\n            var tokenProviderClass = loadClass(oidcClientToTokenProducerName.get(oidcClient));\n            Uni<String> accessTokenProvider = container.<AbstractGraphQLTokenProvider> instance(tokenProviderClass)\n                    .get().getAccessToken();\n            dynamicHeaders.put(\"Authorization\", accessTokenProvider);\n        });\n    }\n\n    private static Class<?> loadClass(String className) {\n        try {\n            return Thread.currentThread().getContextClassLoader().loadClass(className);\n        } catch (ClassNotFoundException e) {\n            throw new RuntimeException(\"Failed to load generated class \" + className, e);\n        }\n    }\n}\n","sourceCodeStart":17,"sourceCodeEnd":39,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/oidc-client-graphql/runtime/src/main/java/io/quarkus/oidc/client/graphql/runtime/OidcGraphQLClientIntegrationRecorder.java#L17-L39","documentation":"Quarkus OIDC GraphQL integration generated a token-provider/ filter class at build time and the recorder now tries to load it by name through the thread-context classloader. If the class is not visible to the current ClassLoader (deployment vs runtime classloader split, or the class was never generated), a ClassNotFoundException is wrapped in this RuntimeException and startup fails.","triggerScenarios":"Calling OidcGraphQLClientIntegrationRecorder.loadClass with a class name that was not produced by the bytecode generation step, or when the current thread context classloader cannot see the generated class (e.g. wrong TCCL in a custom thread or non-standard deployment).","commonSituations":"Upgrading Quarkus where the generated class name changed; running the app inside a custom launcher that resets the context classloader; mixing extension versions so the recorder and generator disagree on the class name.","solutions":["Verify the quarkus-oidc-client-graphql runtime and deployment modules come from the same Quarkus version (mvn dependency:tree).","Ensure the code path runs on a thread whose context classloader is the Quarkus application classloader; wrap custom threads with TCCL set.","Clean rebuild (./mvnw clean install) so the build-time bytecode generation reruns and regenerates the class.","If thrown from your own code, load generated classes via TCCL of the current (Quarkus) thread rather than the recorder's defining classloader."],"exampleFix":"// before\nClass<?> clazz = MyClass.class.getClassLoader().loadClass(generatedClassName);\n// after\nClass<?> clazz = Thread.currentThread().getContextClassLoader().loadClass(generatedClassName);","handlingStrategy":"try-catch","validationCode":"try {\n    Class.forName(className, false, Thread.currentThread().getContextClassLoader());\n} catch (ClassNotFoundException e) {\n    throw new IllegalStateException(\"Generated class not on TCCL: \" + className, e);\n}","typeGuard":"boolean isLoadable(String name) {\n    try { Class.forName(name, false, Thread.currentThread().getContextClassLoader()); return true; }\n    catch (ClassNotFoundException e) { return false; }\n}","tryCatchPattern":"try {\n    Class<?> c = Thread.currentThread().getContextClassLoader().loadClass(className);\n} catch (RuntimeException e) {\n    if (e.getCause() instanceof ClassNotFoundException) {\n        // fail fast with classloader diagnostics: log TCCL and extension versions\n    }\n    throw e;\n}","preventionTips":["Keep all Quarkus extension modules at the same version.","Never assume a class is generated at build time without a corresponding build step producing it.","Set the correct TCCL when spawning threads that load Quarkus-generated classes.","Clean rebuild after upgrading Quarkus so generated class names regenerate."],"tags":["classloader","quarkus","startup","reflection"],"backgroundTag":"classnotfound-generated-class","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"}