You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GraalVM/SpringBoot3/Maven/Jooq原生构建保存数据遇构造记录错误

GraalVM原生构建下jOOQ newRecord()报错的反射配置解决方案

问题原因

GraalVM原生镜像采用静态分析提前编译代码,默认不会保留动态反射所需的元数据。jOOQ的newRecord()方法需要通过反射创建自定义Record实例(如InsecureUserRecord),而原生环境下这些反射元数据被剥离,导致无法构造对象抛出Could not construct new record异常。

手动配置反射规则

创建reflection-config.json文件(建议放在src/main/resources/META-INF/native-image/目录下),添加以下配置:

[
  {
    "name": "org.kbalazs.smart_scrum_poker_backend_native.socket_domain.account_module.repositories.InsecureUserRecord",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  },
  {
    "name": "org.jooq.impl.DefaultRecordFactory",
    "allPublicConstructors": true,
    "allPublicMethods": true
  }
]

配置构建工具引用该文件

  • Maven:在native-maven-plugin中添加配置:
<plugin>
    <groupId>org.graalvm.buildtools</groupId>
    <artifactId>native-maven-plugin</artifactId>
    <version>0.9.28</version>
    <executions>
        <execution>
            <id>build-native</id>
            <goals>
                <goal>compile-no-fork</goal>
            </goals>
            <phase>package</phase>
        </execution>
    </executions>
    <configuration>
        <reflectionConfigFiles>
            <file>${project.basedir}/src/main/resources/META-INF/native-image/reflection-config.json</file>
        </reflectionConfigFiles>
    </configuration>
</plugin>
  • Gradle:在graalvmNative配置中添加构建参数:
graalvmNative {
    binaries {
        main {
            buildArgs.add("-H:ReflectionConfigurationFiles=src/main/resources/META-INF/native-image/reflection-config.json")
        }
    }
}

更高效的自动生成配置方式

使用GraalVM的native-image-agent自动收集运行时所需的反射元数据,避免手动配置遗漏:

  1. 运行JVM版本的应用,带上agent参数:
java -agentlib:native-image-agent=config-output-dir=src/main/resources/META-INF/native-image/ -jar your-app.jar
  1. 执行触发newRecord()报错的操作流程
  2. 关闭应用,agent会自动生成完整的reflection-config.json、resource-config.json等配置文件
  3. 直接使用这些生成的文件进行原生构建即可

补充说明

insertInto()可以正常工作是因为该方法通常使用预编译SQL或直接映射数据,无需动态反射创建Record实例;而newRecord()需要动态实例化自定义Record类,必须依赖反射元数据才能在原生环境运行。

内容的提问来源于stack exchange,提问作者Krizsán Balazs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 06:03:31