diff --git a/spring-core/src/main/java/org/springframework/aot/hint/RuntimeHints.java b/spring-core/src/main/java/org/springframework/aot/hint/RuntimeHints.java index 672af1bd28..a64488ac2a 100644 --- a/spring-core/src/main/java/org/springframework/aot/hint/RuntimeHints.java +++ b/spring-core/src/main/java/org/springframework/aot/hint/RuntimeHints.java @@ -28,6 +28,7 @@ package org.springframework.aot.hint; * recorded as well. * * @author Stephane Nicoll + * @author Janne Valkealahti * @since 6.0 */ public class RuntimeHints { @@ -40,6 +41,8 @@ public class RuntimeHints { private final ProxyHints proxies = new ProxyHints(); + private final ReflectionHints jni = new ReflectionHints(); + /** * Provide access to reflection-based hints. @@ -73,4 +76,12 @@ public class RuntimeHints { return this.proxies; } + /** + * Provide access to jni-based hints. + * @return jni hints + */ + public ReflectionHints jni() { + return this.jni; + } + } diff --git a/spring-core/src/main/java/org/springframework/aot/nativex/NativeConfigurationWriter.java b/spring-core/src/main/java/org/springframework/aot/nativex/NativeConfigurationWriter.java index 192c7c48d0..674602ae65 100644 --- a/spring-core/src/main/java/org/springframework/aot/nativex/NativeConfigurationWriter.java +++ b/spring-core/src/main/java/org/springframework/aot/nativex/NativeConfigurationWriter.java @@ -29,6 +29,7 @@ import org.springframework.aot.hint.SerializationHints; * * @author Sebastien Deleuze * @author Stephane Nicoll + * @author Janne Valkealahti * @since 6.0 * @see Native Image Build Configuration */ @@ -52,6 +53,9 @@ public abstract class NativeConfigurationWriter { hints.resources().resourceBundles().findAny().isPresent()) { writeResourceHints(hints.resources()); } + if (hints.jni().typeHints().findAny().isPresent()) { + writeJniHints(hints.jni()); + } } /** @@ -82,4 +86,9 @@ public abstract class NativeConfigurationWriter { ResourceHintsWriter.INSTANCE.write(writer, hints)); } + private void writeJniHints(ReflectionHints hints) { + writeTo("jni-config.json", writer -> + ReflectionHintsWriter.INSTANCE.write(writer, hints)); + } + } diff --git a/spring-core/src/main/java/org/springframework/aot/nativex/ReflectionHintsWriter.java b/spring-core/src/main/java/org/springframework/aot/nativex/ReflectionHintsWriter.java index 454222b866..3e2f220f0a 100644 --- a/spring-core/src/main/java/org/springframework/aot/nativex/ReflectionHintsWriter.java +++ b/spring-core/src/main/java/org/springframework/aot/nativex/ReflectionHintsWriter.java @@ -34,12 +34,15 @@ import org.springframework.lang.Nullable; /** * Write {@link ReflectionHints} to the JSON output expected by the GraalVM - * {@code native-image} compiler, typically named {@code reflect-config.json}. + * {@code native-image} compiler, typically named {@code reflect-config.json} + * or {@code jni-config.json}. * * @author Sebastien Deleuze * @author Stephane Nicoll + * @author Janne Valkealahti * @since 6.0 * @see Reflection Use in Native Images + * @see Java Native Interface (JNI) in Native Image * @see Native Image Build Configuration */ class ReflectionHintsWriter { diff --git a/spring-core/src/test/java/org/springframework/aot/nativex/FileNativeConfigurationWriterTests.java b/spring-core/src/test/java/org/springframework/aot/nativex/FileNativeConfigurationWriterTests.java index 79537eb4f7..6f297cb3f8 100644 --- a/spring-core/src/test/java/org/springframework/aot/nativex/FileNativeConfigurationWriterTests.java +++ b/spring-core/src/test/java/org/springframework/aot/nativex/FileNativeConfigurationWriterTests.java @@ -49,6 +49,7 @@ import static org.assertj.core.api.Assertions.assertThat; * Tests for {@link FileNativeConfigurationWriter}. * * @author Sebastien Deleuze + * @author Janne Valkealahti */ public class FileNativeConfigurationWriterTests { @@ -149,6 +150,23 @@ public class FileNativeConfigurationWriterTests { ]""", "reflect-config.json"); } + @Test + void jniConfig() throws IOException, JSONException { + // same format as reflection so just test basic file generation + FileNativeConfigurationWriter generator = new FileNativeConfigurationWriter(tempDir); + RuntimeHints hints = new RuntimeHints(); + ReflectionHints jniHints = hints.jni(); + jniHints.registerType(StringDecoder.class, builder -> builder.onReachableType(String.class)); + generator.write(hints); + assertEquals(""" + [ + { + "name": "org.springframework.core.codec.StringDecoder", + "condition": { "typeReachable": "java.lang.String" } + } + ]""", "jni-config.json"); + } + @Test void resourceConfig() throws IOException, JSONException { FileNativeConfigurationWriter generator = new FileNativeConfigurationWriter(tempDir);