elastic/elasticsearch · error · IllegalStateException
Failed to inspect class
Error message
Failed to inspect class {}. Missing class? {} What it means
Thrown by TestingConventionsCheckTask when reflecting over a candidate test class to decide whether it is a JUnit test. Loading/inspecting the class triggers a NoClassDefFoundError because a type the class references is absent from the classpath the check is using. The catch rethrows as IllegalStateException attaching the class name and the underlying error message.
Solutions
- Read the attached NoClassDefFoundError message to identify the missing type, then add the corresponding testImplementation/testCompileOnly dependency to the failing project.
- Run ./gradlew :<project>:dependencies --configuration testCompileClasspath to confirm the missing type's jar is absent.
- If the class is genuinely optional, refactor the test to not reference it, or split the test so the offending type lives in a module where the dependency is present.
- Re-run :<project>:testingConventions to verify.
Example fix
// before: test references @MyCustomAnnotation from a missing dep
// after: add the dependency in build.gradle
dependencies {
testImplementation 'org.example:annotations:1.0'
} Defensive patterns
Strategy: try-catch
Validate before calling
// Before the check, ensure all types referenced by test classes are resolvable // (run a compile + a classpath completeness scan) ./gradlew :<project>:compileTestJava // must pass cleanly first
Try / catch
try { boolean isTest = inspectTestClass(clazz); }
catch (IllegalStateException e) {
if (e.getCause() instanceof NoClassDefFoundError) {
// missing dependency — add it, don't suppress
throw e;
}
throw e;
} Prevention
- Keep testCompileClasspath complete — declare every type a test references.
- Run testingConventions locally before pushing so missing classes surface early.
- After removing a dependency, grep test sources for dangling references.
When it happens
Trigger: The convention check loads classes from compiled test output using a classloader, and calls isJUnit3OrLaterTestMethod / annotation inspection which requires resolving referenced types. If a test class references a type not on the configured test classpath (e.g. a missing transitive dependency, a class only present at runtime), the JVM raises NoClassDefFoundError during reflection.
Common situations: A test class references an annotation or super type from a dependency not declared as a testCompile/testImplementation; running the convention check in isolation without the full test runtime classpath; a recently removed dependency still referenced by legacy test code; shaded/renamed classes after a dependency upgrade.
Related errors
- Failed to load class
- Build directory unknown to gradle
- Unsupported classpath element
- 'branch' not specified.
- Can't export ` ` from build-tools: not found
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/b6a7545e12e50171.
Report an issue: GitHub.
Appendix: source
Thrown at build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/TestingConventionsCheckTask.java:237
Logging.getLogger(TestingConventionsCheckWorkAction.class)
.debug("{} is a test because it has method named '{}'", clazz.getName(), method.getName());
return true;
}
if (isAnnotated(method, junitAnnotation)) {
Logging.getLogger(TestingConventionsCheckWorkAction.class)
.debug(
"{} is a test because it has method '{}' annotated with '{}'",
clazz.getName(),
method.getName(),
junitAnnotation.getName()
);
return true;
}
}
return false;
} catch (NoClassDefFoundError e) {
// Include the message to get more info to get more a more useful message when running Gradle without -s
throw new IllegalStateException("Failed to inspect class " + clazz.getName() + ". Missing class? " + e.getMessage(), e);
}
}
private static boolean matchesTestMethodNamingConvention(Method method) {
return method.getName().startsWith(JUNIT3_TEST_METHOD_PREFIX)
&& Modifier.isStatic(method.getModifiers()) == false
&& method.getReturnType().equals(Void.TYPE);
}
private static boolean isAnnotated(Method method, Class<?> annotation) {
return Stream.of(method.getAnnotations())
.anyMatch(presentAnnotation -> annotation.isAssignableFrom(presentAnnotation.getClass()));
}
private static Class<?> loadClassWithoutInitializing(String name, ClassLoader classLoader) {
try {
return Class.forName(
name,View on GitHub (pinned to db6a809a66)