Skip to content

Instantly share code, notes, and snippets.

Last active February 12, 2023 14:34
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save VR4J/0b30b2d04f95ab37d867353ebcda3e81 to your computer and use it in GitHub Desktop.
Spring Boot 3 RuntimeHints for Jackson Builders
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import lombok.SneakyThrows;
import org.springframework.aot.hint.*;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportRuntimeHints;
import java.util.List;
import java.util.Set;
public class JacksonHints implements RuntimeHintsRegistrar {
private static final String ROOT_PACKAGE = "";
private static final String PACKAGE_SEPARATOR = ".";
private static final String FOLDER_SEPARATOR = "/";
public void registerHints(RuntimeHints hints, ClassLoader loader) {
List<TypeReference> builders = getClasses(loader, ROOT_PACKAGE).stream()
.filter(clazz -> clazz.getAnnotationsByType(JsonPOJOBuilder.class).length > 0)
.registerTypes(builders, TypeHint.builtWith(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_PUBLIC_METHODS))
.registerType(JsonGenerator.class, MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS, MemberCategory.INVOKE_PUBLIC_METHODS);
public Set<Class<?>> getClasses(ClassLoader loader, String name) {
InputStream stream = loader.getResourceAsStream(
name.replaceAll("[" + PACKAGE_SEPARATOR + "]", FOLDER_SEPARATOR)
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
List<String> lines = reader.lines().toList();
Stream<Class<?>> current =
.map(line -> getClass(line, name));
Stream<Class<?>> nested =
.map(child -> setChildPackageName(name, child))
.map(pName -> getClasses(loader, pName))
return Stream.concat(current, nested).collect(Collectors.toSet());
private Class<?> getClass(String className, String packageName) {
return Class.forName(packageName + PACKAGE_SEPARATOR + className.substring(0, className.lastIndexOf(PACKAGE_SEPARATOR)));
private boolean isClassFile(String path) {
return path.endsWith(".class");
private boolean isPackageFolder(String path) {
return ! isClassFile(path);
private String setChildPackageName(String parent, String child) {
return parent + PACKAGE_SEPARATOR + child;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment