JUnit nativeTest 缺 SerializedForm,更新原生可达性元数据
JUnit 原生测试可能缺少 UniqueId.SerializedForm 的序列化构造器元数据。6.1.3 包含可达性处理,临时配置须使用精确类名并在原生测试中验证。
普通 JVM 测试通过,nativeTest 却在启动处报缺少 UniqueId$SerializedForm 的 SerializationConstructorAccessor,可以检查原生序列化可达性元数据。这个精确类名不表示业务测试一定在主动保存对象,也不应该靠删除失败测试绕开。
具体报告涉及 JUnit 6.1.2、Native Build Tools 0.11.4、GraalVM CE 25.0.2;另一个复现从 JUnit 6.0.3 升到 6.1.0 后失败,使用 Java 25 与 Gradle。错误类似:
SerializationConstructorAccessor class not found for declaringClass:
org.junit.platform.engine.UniqueId$SerializedForm
JUnit 的相关初始化会触及序列化构造信息,原生镜像需要知道这个精确类型可被序列化。只给普通反射方法增加配置,不一定覆盖序列化构造器路径;而 GraalVM 21 的对照通过,也不能代表 Java 25 组合已经得到同一覆盖。
JUnit 6.1.3 的正式包提供了对应 reachability metadata,声明这个类型为 serializable。项目可以更新实际参与原生测试的 JUnit Platform、Jupiter 和所用引擎组合。使用 Maven BOM 的项目可按原 dependencyManagement 结构调整:
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>6.1.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
保留现有依赖管理结构和真实使用的测试引擎。Gradle 项目也应更新对应平台约束,并确认 nativeTest 使用的依赖与普通 test 一致;只替换注解 API,不能保证包含元数据的 engine 包已经更新。
暂时无法更新时,原具体复现确认可在测试资源的 native-image 元数据中补充:
[
{
"name": "org.junit.platform.engine.UniqueId$SerializedForm"
}
]
这是 serialization-config.json 的旧格式示例,可放在项目测试资源的 META-INF/native-image/ 下相应位置;它不是把同一数组随意塞进新格式的 reflection 字段。项目已有元数据时合并精确条目,不要覆盖其他必要配置。
然后重新生成原生测试可执行文件,确认这份测试资源确实进入 native-image 输入。运行旧原生二进制,不会因为源码目录多了 JSON 文件而获得新构造器。必要时同时检查 JUnit engine JAR 内的正式 reachability 文件,区分旧包仍在参与构建与资源没有进入镜像。
验收沿原 nativeTest 或项目对应原生测试入口完成,既要确认初始化不再报该类缺失,也要看到预期用例实际运行及结果。普通 JVM 的绿色测试只能作为对照,不能代替原生运行。
这个条目解决明确的 UniqueId 序列化类型缺口。另一个类缺元数据、测试框架版本冲突或业务资源未打包,仍需按新错误诊断;也不能从一份通过的元数据推导所有 JDK 与 GraalVM 组合都兼容。


