{"record":{"id":"8752a6291aa38778","repo":"elastic/elasticsearch","slug":"failed-to-load-class-name-incorrect-classpath","errorCode":null,"errorMessage":"Failed to load class {name}. Incorrect classpath?","messagePattern":"Failed to load class (.+?)\\. Incorrect classpath\\?","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/TestingConventionsCheckTask.java","lineNumber":261,"sourceCode":"                && Modifier.isStatic(method.getModifiers()) == false\n                && method.getReturnType().equals(Void.TYPE);\n        }\n\n        private static boolean isAnnotated(Method method, Class<?> annotation) {\n            return Stream.of(method.getAnnotations())\n                .anyMatch(presentAnnotation -> annotation.isAssignableFrom(presentAnnotation.getClass()));\n        }\n\n        private static Class<?> loadClassWithoutInitializing(String name, ClassLoader classLoader) {\n            try {\n                return Class.forName(\n                    name,\n                    // Don't initialize the class to save time. Not needed for this test and this doesn't share a VM with any other tests.\n                    false,\n                    classLoader\n                );\n            } catch (ClassNotFoundException e) {\n                throw new RuntimeException(\"Failed to load class \" + name + \". Incorrect classpath?\", e);\n            }\n        }\n    }\n\n    private static final class ClassLoadingFileVisitor extends EmptyFileVisitor {\n        private static final String CLASS_POSTFIX = \".class\";\n        private List<String> fullQualifiedClassNames = new ArrayList<>();\n\n        @Override\n        public void visitFile(FileVisitDetails fileVisitDetails) {\n            String fileName = fileVisitDetails.getName();\n            if (fileName.endsWith(CLASS_POSTFIX)) {\n                String packageName = Arrays.stream(fileVisitDetails.getRelativePath().getSegments())\n                    .takeWhile(s -> s.equals(fileName) == false)\n                    .collect(Collectors.joining(\".\"));\n                String simpleClassName = fileName.replace(CLASS_POSTFIX, \"\");\n                String fullQualifiedClassName = packageName + (packageName.isEmpty() ? \"\" : \".\") + simpleClassName;\n                fullQualifiedClassNames.add(fullQualifiedClassName);","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/TestingConventionsCheckTask.java#L243-L279","documentation":"Thrown by TestingConventionsCheckTask.loadClassWithoutInitializing when Class.forName(name, false, classLoader) raises ClassNotFoundException. The visitor collected a .class file's fully-qualified name but the configured classloader cannot resolve that class, indicating the classpath feeding the check is incomplete or inconsistent with the compiled output being scanned.","triggerScenarios":"The ClassLoadingFileVisitor enumerates .class files under compiled output and the task then attempts Class.forName for each; if the classloader was built from a classpath that omits the directory actually being scanned (or a parent/sibling output it depends on), ClassNotFoundException is raised.","commonSituations":"The convention check's classpath does not include the project's own compiled output dir; incremental/parallel build produced a stale class file whose source was removed; cross-project test fixtures referenced but not on the classpath; misconfigured custom SourceSet whose output isn't wired into the check.","solutions":["Confirm the task's classloader classpath includes the compiled class roots being scanned (project.output + test dependencies).","Clean and rebuild the affected project (./gradlew :<project>:clean :<project>:compileTestJava) to remove stale .class files.","If a referenced class was deleted from source but a stale .class remains, a clean removes it; if it's a legitimate external class, add the missing dependency.","Re-run :<project>:testingConventions with --info to see the failing class name, then verify it exists in source."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Ensure scanned class roots are on the classloader's classpath\nList<File> roots = compiledOutputRoots;\nURLClassLoader cl = new URLClassLoader(toUrls(roots), parent);\nfor (String fqcn : visitor.fullQualifiedClassNames) {\n    if (cl.getResource(fqcn.replace('.', '/') + \".class\") == null) {\n        throw new IllegalStateException(\"Scanned class not on classpath: \" + fqcn);\n    }\n}","typeGuard":null,"tryCatchPattern":"try { Class<?> c = loadClassWithoutInitializing(name, cl); }\ncatch (RuntimeException e) {\n    if (e.getCause() instanceof ClassNotFoundException) { /* fix classpath, do not ignore */ }\n    throw e;\n}","preventionTips":["Always include the project's own compiled output in the check's classpath.","Run a clean build before the convention check to eliminate stale .class files.","Wire custom SourceSet outputs explicitly into testingConventions classpath."],"tags":["build","gradle","testing","classpath","classloading"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}