From ef21c6376df1d10116ca5366317225b310332828 Mon Sep 17 00:00:00 2001 From: TheWhiteDog9487 Date: Tue, 26 Aug 2025 17:20:50 +0800 Subject: [PATCH] =?UTF-8?q?Close=20#1=20=E4=BF=AE=E5=A4=8DGraalVM=E6=9E=84?= =?UTF-8?q?=E5=BB=BA=E7=9A=84Native=20Image=E6=97=A0=E6=B3=95=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E7=9A=84=E6=95=85=E9=9A=9C=20=E5=AE=9E=E9=AA=8C?= =?UTF-8?q?=E6=80=A7=E7=89=B9=E6=80=A7=EF=BC=8C=E5=90=8E=E7=BB=AD=E6=9C=89?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E5=86=8D=E8=AF=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 2 +- .../Configuration/GraalVMBuildHints.java | 105 ++++++++++++++++++ .../Configuration/OpenAPIConfiguration.java | 2 +- 3 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 src/main/java/xyz/thewhitedog9487/WebAPI/Configuration/GraalVMBuildHints.java diff --git a/build.gradle.kts b/build.gradle.kts index 511a544..708d77d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,7 +7,7 @@ plugins { } group = "xyz.thewhitedog9487" -version = "0.4.2" +version = "0.4.3" java { toolchain { diff --git a/src/main/java/xyz/thewhitedog9487/WebAPI/Configuration/GraalVMBuildHints.java b/src/main/java/xyz/thewhitedog9487/WebAPI/Configuration/GraalVMBuildHints.java new file mode 100644 index 0000000..4ed15d4 --- /dev/null +++ b/src/main/java/xyz/thewhitedog9487/WebAPI/Configuration/GraalVMBuildHints.java @@ -0,0 +1,105 @@ +package xyz.thewhitedog9487.WebAPI.Configuration; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.aot.hint.TypeReference; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.ImportRuntimeHints; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.type.classreading.CachingMetadataReaderFactory; +import org.springframework.core.type.classreading.MetadataReader; +import org.springframework.util.ClassUtils; + +@Configuration(proxyBeanMethods = false) +@ImportRuntimeHints(RegisterGraalVMBuildHints.class) +class GraalVMBuildHints {} + +/** + * GPT写的,测试了一下能用,先作为实验性内容加入 + * @author ChatGPT GPT5 + */ +class RegisterGraalVMBuildHints implements RuntimeHintsRegistrar{ + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + String basePackage = "discord4j"; + String pattern = "classpath*:" + ClassUtils.convertClassNameToResourcePath(basePackage) + "/**/*.class"; + + PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(classLoader); + CachingMetadataReaderFactory mrf = new CachingMetadataReaderFactory(classLoader); + + int ok = 0, skip = 0; + try { + Resource[] resources = resolver.getResources(pattern); + for (Resource resource : resources) { + if (!resource.isReadable()) { + continue; + } + MetadataReader mr = mrf.getMetadataReader(resource); + String className = mr.getClassMetadata().getClassName(); + try { + // 只处理目标包(防御性判断,避免扫到别的) + if (!className.startsWith(basePackage)) { + continue; + } + Class clazz = ClassUtils.forName(className, classLoader); + // 暴力但稳:把构造器/方法/字段都暴露给反射(含内部类、Builder、$Json) + hints.reflection().registerType(clazz,b -> b.withMembers( + MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, + MemberCategory.INVOKE_DECLARED_METHODS, + MemberCategory.DECLARED_FIELDS)); + ok++; + } catch (Throwable e) { + // 有些类可能因缺失依赖/被 JDK 模块限制而加载失败,跳过即可 + skip++; + } + } + } catch (Exception e) { + throw new RuntimeException("Scan & register discord4j classes failed", e); + } + + hints.reflection().registerType( + TypeReference.of("com.github.benmanes.caffeine.cache.SSLMS"), + builder -> builder.withMembers( + MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, + MemberCategory.INVOKE_DECLARED_METHODS, + MemberCategory.DECLARED_FIELDS + ) + ); + + hints.reflection().registerType( + TypeReference.of("com.github.benmanes.caffeine.cache.SSMS"), + builder -> builder.withMembers( + MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, + MemberCategory.INVOKE_DECLARED_METHODS, + MemberCategory.DECLARED_FIELDS + ) + ); + + hints.reflection().registerType( + TypeReference.of("com.github.benmanes.caffeine.cache.PSLMS"), + builder -> builder.withMembers( + MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, + MemberCategory.INVOKE_DECLARED_METHODS, + MemberCategory.DECLARED_FIELDS + ) + ); + + hints.reflection().registerType( + TypeReference.of("com.github.benmanes.caffeine.cache.PSMS"), + builder -> builder.withMembers( + MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, + MemberCategory.INVOKE_DECLARED_METHODS, + MemberCategory.DECLARED_FIELDS + ) + ); + + + // 用 System.out 打印(AOT 阶段 SLF4J 常常是 NOP) + System.out.println("[Discord4jJsonHints] registered classes: " + ok + ", skipped: " + skip); + + } + +} diff --git a/src/main/java/xyz/thewhitedog9487/WebAPI/Configuration/OpenAPIConfiguration.java b/src/main/java/xyz/thewhitedog9487/WebAPI/Configuration/OpenAPIConfiguration.java index d793ab3..7c1fd11 100644 --- a/src/main/java/xyz/thewhitedog9487/WebAPI/Configuration/OpenAPIConfiguration.java +++ b/src/main/java/xyz/thewhitedog9487/WebAPI/Configuration/OpenAPIConfiguration.java @@ -23,7 +23,7 @@ class OpenAPIConfiguration { .contact(new Contact() .name("TheWhiteDog9487") .url("https://www.github.com/TheWhiteDog9487/WebAPI")) - .version("0.4.2") + .version("0.4.3") .license(new License() .name("WTFPL") .url("https://spdx.org/licenses/WTFPL")) )