Switch sample jni config programmatic

- Now generating jni-config.json via hints to test
  that side instead of having manually crafted file.
- Relates #490
This commit is contained in:
Janne Valkealahti
2022-09-06 19:48:02 +01:00
parent a9a420df22
commit a79d2a6c53
2 changed files with 295 additions and 287 deletions

View File

@@ -15,6 +15,7 @@
*/
package org.springframework.shell.samples.config;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -24,6 +25,7 @@ import org.springframework.aot.hint.ReflectionHints;
import org.springframework.aot.hint.ResourceHints;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.aot.hint.TypeHint;
import org.springframework.aot.hint.TypeReference;
public class SamplesRuntimeHints implements RuntimeHintsRegistrar {
@@ -33,6 +35,7 @@ public class SamplesRuntimeHints implements RuntimeHintsRegistrar {
ResourceHints resource = hints.resources();
ProxyHints proxy = hints.proxies();
ReflectionHints reflection = hints.reflection();
ReflectionHints jni = hints.jni();
// should go graalvm-reachability-metadata
registerResources(resource);
// should go graalvm-reachability-metadata
@@ -57,6 +60,7 @@ public class SamplesRuntimeHints implements RuntimeHintsRegistrar {
"org.jline.terminal.impl.jna.win.Kernel32$FOCUS_EVENT_RECORD",
"org.jline.terminal.impl.jna.win.Kernel32$SMALL_RECT",
"org.jline.terminal.impl.jna.win.Kernel32$UnionChar");
registerJni(jni);
}
private void registerResources(ResourceHints resource) {
@@ -77,8 +81,298 @@ public class SamplesRuntimeHints implements RuntimeHintsRegistrar {
});
}
private Iterable<TypeReference> typeReferences(String... classNames) {
private List<TypeReference> typeReferences(String... classNames) {
return Stream.of(classNames).map(TypeReference::of).collect(Collectors.toList());
}
private void registerJni(ReflectionHints jni) {
TypeReference reachableType = TypeReference.of("org.jline.terminal.impl.jna.win.Kernel32");
registerForJni(jni, reachableType, "com.sun.jna.Callback",
Methods.of(),
Fields.of());
registerForJni(jni, reachableType, "com.sun.jna.CallbackReference",
Methods.of(
Method.of("getCallback", "java.lang.Class", "com.sun.jna.Pointer", "boolean"),
Method.of("getFunctionPointer", "com.sun.jna.Callback", "boolean"),
Method.of("getNativeString", "java.lang.Object", "boolean"),
Method.of("initializeThread", "com.sun.jna.Callback",
"com.sun.jna.CallbackReference$AttachOptions")),
Fields.of());
registerForJni(jni, reachableType, "com.sun.jna.CallbackReference$AttachOptions",
Methods.of(),
Fields.of());
registerForJni(jni, reachableType, "com.sun.jna.FromNativeConverter",
Methods.of(
Method.of("nativeType")
),
Fields.of());
registerForJni(jni, reachableType, "com.sun.jna.IntegerType",
Methods.of(),
Fields.of("value"));
registerForJni(jni, reachableType, "com.sun.jna.JNIEnv",
Methods.of(),
Fields.of());
registerForJni(jni, reachableType, "com.sun.jna.Native",
Methods.of(
Method.of("dispose"),
Method.of("fromNative", "com.sun.jna.FromNativeConverter", "java.lang.Object",
"java.lang.reflect.Method"),
Method.of("fromNative", "java.lang.Class", "java.lang.Object"),
Method.of("fromNative", "java.lang.reflect.Method", "java.lang.Object"),
Method.of("nativeType", "java.lang.Class"),
Method.of("toNative", "com.sun.jna.ToNativeConverter","java.lang.Object")
),
Fields.of());
registerForJni(jni, reachableType, "com.sun.jna.Native$ffi_callback",
Methods.of(
Method.of("invoke", "long", "long", "long")
),
Fields.of());
registerForJni(jni, reachableType, "com.sun.jna.NativeMapped",
Methods.of(
Method.of("toNative")
),
Fields.of());
registerForJni(jni, reachableType, "com.sun.jna.Pointer",
Methods.of(
Method.of("<init>", "long")
),
Fields.of("peer"));
registerForJni(jni, reachableType, "com.sun.jna.PointerType",
Methods.of(),
Fields.of("pointer"));
registerForJni(jni, reachableType, "com.sun.jna.Structure",
Methods.of(
Method.of("autoRead"),
Method.of("autoWrite"),
Method.of("getTypeInfo"),
Method.of("newInstance", "java.lang.Class", "long")
),
Fields.of("memory", "typeInfo"));
registerForJni(jni, reachableType, "com.sun.jna.Structure$ByValue",
Methods.of(),
Fields.of());
registerForJni(jni, reachableType, "com.sun.jna.Structure$FFIType$FFITypes",
Methods.of(),
Fields.of("ffi_type_double", "ffi_type_float", "ffi_type_longdouble", "ffi_type_pointer",
"ffi_type_sint16", "ffi_type_sint32", "ffi_type_sint64", "ffi_type_sint8", "ffi_type_uint16",
"ffi_type_uint32", "ffi_type_uint64", "ffi_type_uint8",
"ffi_type_void"));
registerForJni(jni, reachableType, "com.sun.jna.WString",
Methods.of(
Method.of("<init>", "java.lang.String")
),
Fields.of());
registerForJni(jni, reachableType, "java.lang.Boolean",
Methods.of(
Method.of("<init>", "boolean")
),
Fields.of("TYPE", "value"));
registerForJni(jni, reachableType, "java.lang.Byte",
Methods.of(
Method.of("<init>", "byte")
),
Fields.of("TYPE", "value"));
registerForJni(jni, reachableType, "java.lang.Character",
Methods.of(
Method.of("<init>", "char")
),
Fields.of("TYPE", "value"));
registerForJni(jni, reachableType, "java.lang.Class",
Methods.of(
Method.of("getComponentType")
),
Fields.of());
registerForJni(jni, reachableType, "java.lang.Double",
Methods.of(
Method.of("<init>", "double")
),
Fields.of("TYPE", "value"));
registerForJni(jni, reachableType, "java.lang.Float",
Methods.of(
Method.of("<init>", "float")
),
Fields.of("TYPE", "value"));
registerForJni(jni, reachableType, "java.lang.Integer",
Methods.of(
Method.of("<init>", "int")
),
Fields.of("TYPE", "value"));
registerForJni(jni, reachableType, "java.lang.Long",
Methods.of(
Method.of("<init>", "long")
),
Fields.of("TYPE", "value"));
registerForJni(jni, reachableType, "java.lang.Object",
Methods.of(
Method.of("toString")
),
Fields.of());
registerForJni(jni, reachableType, "java.lang.Short",
Methods.of(
Method.of("<init>", "short")
),
Fields.of("TYPE", "value"));
registerForJni(jni, reachableType, "java.lang.String",
Methods.of(
Method.of("<init>", "byte[]"),
Method.of("<init>", "byte[]", "java.lang.String"),
Method.of("getBytes"),
Method.of("getBytes", "java.lang.String"),
Method.of("toCharArray")
),
Fields.of());
registerForJni(jni, reachableType, "java.lang.System",
Methods.of(
Method.of("getProperty", "java.lang.String")
),
Fields.of());
registerForJni(jni, reachableType, "java.lang.UnsatisfiedLinkError",
Methods.of(
Method.of("<init>","java.lang.String")
),
Fields.of());
registerForJni(jni, reachableType, "java.lang.Void",
Methods.of(),
Fields.of("TYPE"));
registerForJni(jni, reachableType, "java.lang.reflect.Method",
Methods.of(
Method.of("getParameterTypes"),
Method.of("getReturnType")
),
Fields.of());
registerForJni(jni, reachableType, "java.nio.Buffer",
Methods.of(
Method.of("array"),
Method.of("arrayOffset")
),
Fields.of());
registerForJni(jni, reachableType, "java.nio.ByteBuffer",
Methods.of(
Method.of("array"),
Method.of("arrayOffset")
),
Fields.of());
registerForJni(jni, reachableType, "java.nio.CharBuffer",
Methods.of(
Method.of("array"),
Method.of("arrayOffset")
),
Fields.of());
registerForJni(jni, reachableType, "java.nio.DoubleBuffer",
Methods.of(
Method.of("array"),
Method.of("arrayOffset")
),
Fields.of());
registerForJni(jni, reachableType, "java.nio.FloatBuffer",
Methods.of(
Method.of("array"),
Method.of("arrayOffset")
),
Fields.of());
registerForJni(jni, reachableType, "java.nio.IntBuffer",
Methods.of(
Method.of("array"),
Method.of("arrayOffset")
),
Fields.of());
registerForJni(jni, reachableType, "java.nio.LongBuffer",
Methods.of(
Method.of("array"),
Method.of("arrayOffset")
),
Fields.of());
registerForJni(jni, reachableType, "java.nio.ShortBuffer",
Methods.of(
Method.of("array"),
Method.of("arrayOffset")
),
Fields.of());
}
private void registerForJni(ReflectionHints jni, TypeReference reachableType, String type,
Methods methods, Fields fields) {
jni.registerType(TypeReference.of(type), hint -> {
hint.onReachableType(reachableType);
methods.withHints(hint);
fields.withHints(hint);
});
}
record Fields(String... names) {
static Fields of(String... names) {
return new Fields(names);
}
void withHints(TypeHint.Builder hint) {
Stream.of(names()).forEach(f -> hint.withField(f));
}
}
record Method(String name, String... parameterTypes) {
static Method of(String name, String... parameterTypes) {
return new Method(name, parameterTypes);
}
private List<TypeReference> asTypeReferences() {
return Stream.of(parameterTypes).map(TypeReference::of).collect(Collectors.toList());
}
void withHints(TypeHint.Builder hint) {
hint.withMethod(name, asTypeReferences());
}
}
record Methods(Method... methods) {
static Methods of(Method... methods) {
return new Methods(methods);
}
void withHints(TypeHint.Builder hint) {
Stream.of(methods()).forEach(m -> m.withHints(hint));
}
}
}

View File

@@ -1,286 +0,0 @@
[
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"com.sun.jna.Callback"
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"com.sun.jna.CallbackReference",
"methods":[
{"name":"getCallback","parameterTypes":["java.lang.Class","com.sun.jna.Pointer","boolean"] },
{"name":"getFunctionPointer","parameterTypes":["com.sun.jna.Callback","boolean"] },
{"name":"getNativeString","parameterTypes":["java.lang.Object","boolean"] },
{"name":"initializeThread","parameterTypes":["com.sun.jna.Callback","com.sun.jna.CallbackReference$AttachOptions"] }
]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"com.sun.jna.CallbackReference$AttachOptions"
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"com.sun.jna.FromNativeConverter",
"methods":[{"name":"nativeType","parameterTypes":[] }]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"com.sun.jna.IntegerType",
"fields":[{"name":"value"}]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"com.sun.jna.JNIEnv"
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"com.sun.jna.Native",
"methods":[
{"name":"dispose","parameterTypes":[] },
{"name":"fromNative","parameterTypes":["com.sun.jna.FromNativeConverter","java.lang.Object","java.lang.reflect.Method"] },
{"name":"fromNative","parameterTypes":["java.lang.Class","java.lang.Object"] },
{"name":"fromNative","parameterTypes":["java.lang.reflect.Method","java.lang.Object"] },
{"name":"nativeType","parameterTypes":["java.lang.Class"] },
{"name":"toNative","parameterTypes":["com.sun.jna.ToNativeConverter","java.lang.Object"] }
]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"com.sun.jna.Native$ffi_callback",
"methods":[{"name":"invoke","parameterTypes":["long","long","long"] }]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"com.sun.jna.NativeMapped",
"methods":[{"name":"toNative","parameterTypes":[] }]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"com.sun.jna.Pointer",
"fields":[{"name":"peer"}],
"methods":[{"name":"<init>","parameterTypes":["long"] }]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"com.sun.jna.PointerType",
"fields":[{"name":"pointer"}]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"com.sun.jna.Structure",
"fields":[
{"name":"memory"},
{"name":"typeInfo"}
],
"methods":[
{"name":"autoRead","parameterTypes":[] },
{"name":"autoWrite","parameterTypes":[] },
{"name":"getTypeInfo","parameterTypes":[] },
{"name":"newInstance","parameterTypes":["java.lang.Class","long"] }
]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"com.sun.jna.Structure$ByValue"
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"com.sun.jna.Structure$FFIType$FFITypes",
"fields":[
{"name":"ffi_type_double"},
{"name":"ffi_type_float"},
{"name":"ffi_type_longdouble"},
{"name":"ffi_type_pointer"},
{"name":"ffi_type_sint16"},
{"name":"ffi_type_sint32"},
{"name":"ffi_type_sint64"},
{"name":"ffi_type_sint8"},
{"name":"ffi_type_uint16"},
{"name":"ffi_type_uint32"},
{"name":"ffi_type_uint64"},
{"name":"ffi_type_uint8"},
{"name":"ffi_type_void"}
]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"com.sun.jna.WString",
"methods":[{"name":"<init>","parameterTypes":["java.lang.String"] }]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"java.lang.Boolean",
"fields":[
{"name":"TYPE"},
{"name":"value"}
],
"methods":[{"name":"<init>","parameterTypes":["boolean"] }]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"java.lang.Byte",
"fields":[
{"name":"TYPE"},
{"name":"value"}
],
"methods":[{"name":"<init>","parameterTypes":["byte"] }]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"java.lang.Character",
"fields":[
{"name":"TYPE"},
{"name":"value"}
],
"methods":[{"name":"<init>","parameterTypes":["char"] }]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"java.lang.Class",
"methods":[{"name":"getComponentType","parameterTypes":[] }]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"java.lang.Double",
"fields":[
{"name":"TYPE"},
{"name":"value"}
],
"methods":[{"name":"<init>","parameterTypes":["double"] }]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"java.lang.Float",
"fields":[
{"name":"TYPE"},
{"name":"value"}
],
"methods":[{"name":"<init>","parameterTypes":["float"] }]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"java.lang.Integer",
"fields":[
{"name":"TYPE"},
{"name":"value"}
],
"methods":[{"name":"<init>","parameterTypes":["int"] }]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"java.lang.Long",
"fields":[
{"name":"TYPE"},
{"name":"value"}
],
"methods":[{"name":"<init>","parameterTypes":["long"] }]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"java.lang.Object",
"methods":[{"name":"toString","parameterTypes":[] }]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"java.lang.Short",
"fields":[
{"name":"TYPE"},
{"name":"value"}
],
"methods":[{"name":"<init>","parameterTypes":["short"] }]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"java.lang.String",
"methods":[
{"name":"<init>","parameterTypes":["byte[]"] },
{"name":"<init>","parameterTypes":["byte[]","java.lang.String"] },
{"name":"getBytes","parameterTypes":[] },
{"name":"getBytes","parameterTypes":["java.lang.String"] },
{"name":"toCharArray","parameterTypes":[] }
]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"java.lang.System",
"methods":[{"name":"getProperty","parameterTypes":["java.lang.String"] }]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.$Proxy43"},
"name":"java.lang.UnsatisfiedLinkError",
"methods":[{"name":"<init>","parameterTypes":["java.lang.String"] }]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"java.lang.Void",
"fields":[{"name":"TYPE"}]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"java.lang.reflect.Method",
"methods":[
{"name":"getParameterTypes","parameterTypes":[] },
{"name":"getReturnType","parameterTypes":[] }
]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"java.nio.Buffer",
"methods":[{"name":"position","parameterTypes":[] }]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"java.nio.ByteBuffer",
"methods":[
{"name":"array","parameterTypes":[] },
{"name":"arrayOffset","parameterTypes":[] }
]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"java.nio.CharBuffer",
"methods":[
{"name":"array","parameterTypes":[] },
{"name":"arrayOffset","parameterTypes":[] }
]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"java.nio.DoubleBuffer",
"methods":[
{"name":"array","parameterTypes":[] },
{"name":"arrayOffset","parameterTypes":[] }
]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"java.nio.FloatBuffer",
"methods":[
{"name":"array","parameterTypes":[] },
{"name":"arrayOffset","parameterTypes":[] }
]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"java.nio.IntBuffer",
"methods":[
{"name":"array","parameterTypes":[] },
{"name":"arrayOffset","parameterTypes":[] }
]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"java.nio.LongBuffer",
"methods":[
{"name":"array","parameterTypes":[] },
{"name":"arrayOffset","parameterTypes":[] }
]
},
{
"condition":{"typeReachable":"org.jline.terminal.impl.jna.win.Kernel32"},
"name":"java.nio.ShortBuffer",
"methods":[
{"name":"array","parameterTypes":[] },
{"name":"arrayOffset","parameterTypes":[] }
]
}
]