spring-projects/spring-ai · error · RuntimeException
ClassNotFoundException (wrapped RuntimeException)
Error message
ClassNotFoundException (wrapped RuntimeException)
What it means
AiRuntimeHints.findJsonAnnotatedClassesInPackage scans classpath resources for @JsonSerializable/JSON-annotated classes to register them for native-image reflection; if Class.forName fails to load a discovered class name it wraps ClassNotFoundException in a RuntimeException. This typically indicates inconsistent classpath metadata.
Source
Thrown at spring-ai-model/src/main/java/org/springframework/ai/aot/AiRuntimeHints.java:65
private static final Log log = LogFactory.getLog(AiRuntimeHints.class);
/**
* Finds classes in a package that are annotated with JsonInclude or have Jackson
* annotations.
* @param packageName The name of the package to search for annotated classes.
* @return A set of TypeReference objects representing the annotated classes found.
*/
public static Set<TypeReference> findJsonAnnotatedClassesInPackage(String packageName) {
var annotationTypeFilter = new AnnotationTypeFilter(JsonInclude.class);
TypeFilter typeFilter = (metadataReader, metadataReaderFactory) -> {
try {
var clazz = Class.forName(metadataReader.getClassMetadata().getClassName());
return annotationTypeFilter.match(metadataReader, metadataReaderFactory)
|| !discoverJacksonAnnotatedTypesFromRootType(clazz).isEmpty();
}
catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
};
return findClassesInPackage(packageName, typeFilter);
}
/**
* Finds classes in a package that are annotated with JsonInclude or have Jackson
* annotations.
* @param packageClass The class in the package to search for annotated classes.
* @return A set of TypeReference objects representing the annotated classes found.
*/
public static Set<TypeReference> findJsonAnnotatedClassesInPackage(Class<?> packageClass) {
return findJsonAnnotatedClassesInPackage(packageClass.getPackageName());
}
/**
* Finds all classes in the specified package that match the given type filter.View on GitHub (pinned to 98a7beda4f)
Solutions
- Run a clean build (mvn clean) to remove stale classpath metadata
- Verify the class named in the message still exists and matches the scanned package
- Fix shading/relocation config so scanned classes remain loadable in the native image
- Update the packageName passed to findJsonAnnotatedClassesInPackage to a package that actually contains the JSON-annotated types
Example fix
// before
new AiRuntimeHints().findJsonAnnotatedClassesInPackage("com.example.model");
// after (after clean rebuild, narrow to existing package)
Assert.isTrue(SomeJsonDto.class.getPackageName().startsWith("com.example.model"),
"Scanned package no longer matches relocated classes");
new AiRuntimeHints().findJsonAnnotatedClassesInPackage("com.example.model"); Defensive patterns
Strategy: try-catch
Validate before calling
// before registering hints, verify the scanned classes resolve
Class.forName("com.example.model.SomeJsonDto", false, getClass().getClassLoader()); Try / catch
try {
hints.findJsonAnnotatedClassesInPackage(pkg);
} catch (RuntimeException e) {
if (e.getCause() instanceof ClassNotFoundException cnfe) {
throw new IllegalStateException("Stale classpath metadata for " + cnfe.getMessage() + "; run a clean build");
}
throw e;
} Prevention
- Run mvn clean after package refactors before native-image builds
- Avoid shading/relocation of scanned packages
- Keep scanned package names in sync with actual code layout
When it happens
Trigger: Running native-image hint registration when a class listed in classpath metadata was removed/renamed, shading broke class visibility, or a scanning filter matched a class not present at runtime.
Common situations: GraalVM native-image builds after package refactor; fat-jar shading that excludes scanned classes; duplicate/stale class entries from old build artifacts.
Related errors
- IOException (wrapped RuntimeException)
- Failed to read resource
- Failed to extract record field types
- Could not access method:
- Failed to instantiate ToolCallResultConverter:
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/172d78c33d100bfe.
Report an issue: GitHub.