Skip to content

Commit a79d2a6

Browse files
committed
Switch sample jni config programmatic
- Now generating jni-config.json via hints to test that side instead of having manually crafted file. - Relates #490
1 parent a9a420d commit a79d2a6

File tree

2 files changed

+295
-287
lines changed

2 files changed

+295
-287
lines changed

spring-shell-samples/src/main/java/org/springframework/shell/samples/config/SamplesRuntimeHints.java

Lines changed: 295 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.springframework.shell.samples.config;
1717

18+
import java.util.List;
1819
import java.util.stream.Collectors;
1920
import java.util.stream.Stream;
2021

@@ -24,6 +25,7 @@
2425
import org.springframework.aot.hint.ResourceHints;
2526
import org.springframework.aot.hint.RuntimeHints;
2627
import org.springframework.aot.hint.RuntimeHintsRegistrar;
28+
import org.springframework.aot.hint.TypeHint;
2729
import org.springframework.aot.hint.TypeReference;
2830

2931
public class SamplesRuntimeHints implements RuntimeHintsRegistrar {
@@ -33,6 +35,7 @@ public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
3335
ResourceHints resource = hints.resources();
3436
ProxyHints proxy = hints.proxies();
3537
ReflectionHints reflection = hints.reflection();
38+
ReflectionHints jni = hints.jni();
3639
// should go graalvm-reachability-metadata
3740
registerResources(resource);
3841
// should go graalvm-reachability-metadata
@@ -57,6 +60,7 @@ public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
5760
"org.jline.terminal.impl.jna.win.Kernel32$FOCUS_EVENT_RECORD",
5861
"org.jline.terminal.impl.jna.win.Kernel32$SMALL_RECT",
5962
"org.jline.terminal.impl.jna.win.Kernel32$UnionChar");
63+
registerJni(jni);
6064
}
6165

6266
private void registerResources(ResourceHints resource) {
@@ -77,8 +81,298 @@ private void registerForMostReflection(ReflectionHints reflection, String... cla
7781
});
7882
}
7983

80-
private Iterable<TypeReference> typeReferences(String... classNames) {
84+
private List<TypeReference> typeReferences(String... classNames) {
8185
return Stream.of(classNames).map(TypeReference::of).collect(Collectors.toList());
8286
}
8387

88+
private void registerJni(ReflectionHints jni) {
89+
TypeReference reachableType = TypeReference.of("org.jline.terminal.impl.jna.win.Kernel32");
90+
91+
registerForJni(jni, reachableType, "com.sun.jna.Callback",
92+
Methods.of(),
93+
Fields.of());
94+
95+
registerForJni(jni, reachableType, "com.sun.jna.CallbackReference",
96+
Methods.of(
97+
Method.of("getCallback", "java.lang.Class", "com.sun.jna.Pointer", "boolean"),
98+
Method.of("getFunctionPointer", "com.sun.jna.Callback", "boolean"),
99+
Method.of("getNativeString", "java.lang.Object", "boolean"),
100+
Method.of("initializeThread", "com.sun.jna.Callback",
101+
"com.sun.jna.CallbackReference$AttachOptions")),
102+
Fields.of());
103+
104+
registerForJni(jni, reachableType, "com.sun.jna.CallbackReference$AttachOptions",
105+
Methods.of(),
106+
Fields.of());
107+
108+
registerForJni(jni, reachableType, "com.sun.jna.FromNativeConverter",
109+
Methods.of(
110+
Method.of("nativeType")
111+
),
112+
Fields.of());
113+
114+
registerForJni(jni, reachableType, "com.sun.jna.IntegerType",
115+
Methods.of(),
116+
Fields.of("value"));
117+
118+
registerForJni(jni, reachableType, "com.sun.jna.JNIEnv",
119+
Methods.of(),
120+
Fields.of());
121+
122+
registerForJni(jni, reachableType, "com.sun.jna.Native",
123+
Methods.of(
124+
Method.of("dispose"),
125+
Method.of("fromNative", "com.sun.jna.FromNativeConverter", "java.lang.Object",
126+
"java.lang.reflect.Method"),
127+
Method.of("fromNative", "java.lang.Class", "java.lang.Object"),
128+
Method.of("fromNative", "java.lang.reflect.Method", "java.lang.Object"),
129+
Method.of("nativeType", "java.lang.Class"),
130+
Method.of("toNative", "com.sun.jna.ToNativeConverter","java.lang.Object")
131+
),
132+
Fields.of());
133+
134+
registerForJni(jni, reachableType, "com.sun.jna.Native$ffi_callback",
135+
Methods.of(
136+
Method.of("invoke", "long", "long", "long")
137+
),
138+
Fields.of());
139+
140+
registerForJni(jni, reachableType, "com.sun.jna.NativeMapped",
141+
Methods.of(
142+
Method.of("toNative")
143+
),
144+
Fields.of());
145+
146+
registerForJni(jni, reachableType, "com.sun.jna.Pointer",
147+
Methods.of(
148+
Method.of("<init>", "long")
149+
),
150+
Fields.of("peer"));
151+
152+
registerForJni(jni, reachableType, "com.sun.jna.PointerType",
153+
Methods.of(),
154+
Fields.of("pointer"));
155+
156+
registerForJni(jni, reachableType, "com.sun.jna.Structure",
157+
Methods.of(
158+
Method.of("autoRead"),
159+
Method.of("autoWrite"),
160+
Method.of("getTypeInfo"),
161+
Method.of("newInstance", "java.lang.Class", "long")
162+
),
163+
Fields.of("memory", "typeInfo"));
164+
165+
registerForJni(jni, reachableType, "com.sun.jna.Structure$ByValue",
166+
Methods.of(),
167+
Fields.of());
168+
169+
registerForJni(jni, reachableType, "com.sun.jna.Structure$FFIType$FFITypes",
170+
Methods.of(),
171+
Fields.of("ffi_type_double", "ffi_type_float", "ffi_type_longdouble", "ffi_type_pointer",
172+
"ffi_type_sint16", "ffi_type_sint32", "ffi_type_sint64", "ffi_type_sint8", "ffi_type_uint16",
173+
"ffi_type_uint32", "ffi_type_uint64", "ffi_type_uint8",
174+
"ffi_type_void"));
175+
176+
registerForJni(jni, reachableType, "com.sun.jna.WString",
177+
Methods.of(
178+
Method.of("<init>", "java.lang.String")
179+
),
180+
Fields.of());
181+
182+
registerForJni(jni, reachableType, "java.lang.Boolean",
183+
Methods.of(
184+
Method.of("<init>", "boolean")
185+
),
186+
Fields.of("TYPE", "value"));
187+
188+
registerForJni(jni, reachableType, "java.lang.Byte",
189+
Methods.of(
190+
Method.of("<init>", "byte")
191+
),
192+
Fields.of("TYPE", "value"));
193+
194+
registerForJni(jni, reachableType, "java.lang.Character",
195+
Methods.of(
196+
Method.of("<init>", "char")
197+
),
198+
Fields.of("TYPE", "value"));
199+
200+
registerForJni(jni, reachableType, "java.lang.Class",
201+
Methods.of(
202+
Method.of("getComponentType")
203+
),
204+
Fields.of());
205+
206+
registerForJni(jni, reachableType, "java.lang.Double",
207+
Methods.of(
208+
Method.of("<init>", "double")
209+
),
210+
Fields.of("TYPE", "value"));
211+
212+
registerForJni(jni, reachableType, "java.lang.Float",
213+
Methods.of(
214+
Method.of("<init>", "float")
215+
),
216+
Fields.of("TYPE", "value"));
217+
218+
registerForJni(jni, reachableType, "java.lang.Integer",
219+
Methods.of(
220+
Method.of("<init>", "int")
221+
),
222+
Fields.of("TYPE", "value"));
223+
224+
registerForJni(jni, reachableType, "java.lang.Long",
225+
Methods.of(
226+
Method.of("<init>", "long")
227+
),
228+
Fields.of("TYPE", "value"));
229+
230+
registerForJni(jni, reachableType, "java.lang.Object",
231+
Methods.of(
232+
Method.of("toString")
233+
),
234+
Fields.of());
235+
236+
registerForJni(jni, reachableType, "java.lang.Short",
237+
Methods.of(
238+
Method.of("<init>", "short")
239+
),
240+
Fields.of("TYPE", "value"));
241+
242+
registerForJni(jni, reachableType, "java.lang.String",
243+
Methods.of(
244+
Method.of("<init>", "byte[]"),
245+
Method.of("<init>", "byte[]", "java.lang.String"),
246+
Method.of("getBytes"),
247+
Method.of("getBytes", "java.lang.String"),
248+
Method.of("toCharArray")
249+
),
250+
Fields.of());
251+
252+
registerForJni(jni, reachableType, "java.lang.System",
253+
Methods.of(
254+
Method.of("getProperty", "java.lang.String")
255+
),
256+
Fields.of());
257+
258+
registerForJni(jni, reachableType, "java.lang.UnsatisfiedLinkError",
259+
Methods.of(
260+
Method.of("<init>","java.lang.String")
261+
),
262+
Fields.of());
263+
264+
registerForJni(jni, reachableType, "java.lang.Void",
265+
Methods.of(),
266+
Fields.of("TYPE"));
267+
268+
registerForJni(jni, reachableType, "java.lang.reflect.Method",
269+
Methods.of(
270+
Method.of("getParameterTypes"),
271+
Method.of("getReturnType")
272+
),
273+
Fields.of());
274+
275+
registerForJni(jni, reachableType, "java.nio.Buffer",
276+
Methods.of(
277+
Method.of("array"),
278+
Method.of("arrayOffset")
279+
),
280+
Fields.of());
281+
282+
registerForJni(jni, reachableType, "java.nio.ByteBuffer",
283+
Methods.of(
284+
Method.of("array"),
285+
Method.of("arrayOffset")
286+
),
287+
Fields.of());
288+
289+
registerForJni(jni, reachableType, "java.nio.CharBuffer",
290+
Methods.of(
291+
Method.of("array"),
292+
Method.of("arrayOffset")
293+
),
294+
Fields.of());
295+
296+
registerForJni(jni, reachableType, "java.nio.DoubleBuffer",
297+
Methods.of(
298+
Method.of("array"),
299+
Method.of("arrayOffset")
300+
),
301+
Fields.of());
302+
303+
registerForJni(jni, reachableType, "java.nio.FloatBuffer",
304+
Methods.of(
305+
Method.of("array"),
306+
Method.of("arrayOffset")
307+
),
308+
Fields.of());
309+
310+
registerForJni(jni, reachableType, "java.nio.IntBuffer",
311+
Methods.of(
312+
Method.of("array"),
313+
Method.of("arrayOffset")
314+
),
315+
Fields.of());
316+
317+
registerForJni(jni, reachableType, "java.nio.LongBuffer",
318+
Methods.of(
319+
Method.of("array"),
320+
Method.of("arrayOffset")
321+
),
322+
Fields.of());
323+
324+
registerForJni(jni, reachableType, "java.nio.ShortBuffer",
325+
Methods.of(
326+
Method.of("array"),
327+
Method.of("arrayOffset")
328+
),
329+
Fields.of());
330+
331+
}
332+
333+
private void registerForJni(ReflectionHints jni, TypeReference reachableType, String type,
334+
Methods methods, Fields fields) {
335+
jni.registerType(TypeReference.of(type), hint -> {
336+
hint.onReachableType(reachableType);
337+
methods.withHints(hint);
338+
fields.withHints(hint);
339+
});
340+
}
341+
342+
record Fields(String... names) {
343+
344+
static Fields of(String... names) {
345+
return new Fields(names);
346+
}
347+
348+
void withHints(TypeHint.Builder hint) {
349+
Stream.of(names()).forEach(f -> hint.withField(f));
350+
}
351+
}
352+
353+
record Method(String name, String... parameterTypes) {
354+
355+
static Method of(String name, String... parameterTypes) {
356+
return new Method(name, parameterTypes);
357+
}
358+
359+
private List<TypeReference> asTypeReferences() {
360+
return Stream.of(parameterTypes).map(TypeReference::of).collect(Collectors.toList());
361+
}
362+
363+
void withHints(TypeHint.Builder hint) {
364+
hint.withMethod(name, asTypeReferences());
365+
}
366+
}
367+
368+
record Methods(Method... methods) {
369+
370+
static Methods of(Method... methods) {
371+
return new Methods(methods);
372+
}
373+
374+
void withHints(TypeHint.Builder hint) {
375+
Stream.of(methods()).forEach(m -> m.withHints(hint));
376+
}
377+
}
84378
}

0 commit comments

Comments
 (0)