---
title: "native 故障排查与 FAQ"
---

native 构建出错是常态（[native 导引](/article/1218) 里有心理准备提示）。本文把最常见的报错、定位思路和常见问题汇总成一张对照表，按图索骥即可。


### 1、典型报错对照表

| 报错/现象 | 原因 | 处理 |
| --- | --- | --- |
| `Abstract classes are not supported as proxy components` | 代理组件是抽象类 | 去掉代理或改造类（见 《native 约束与兼容性》） |
| `Final classes are not supported as proxy components` | 代理组件是 final 类 | 去掉 final |
| `Not public classes are not supported as proxy components` | 代理组件不是 public | 改成 public |
| `Generic type classes are not supported as proxy components` | 代理组件是泛型类 | 去掉类型参数 |
| 打包时提示连接 DB/Redis 失败 | AOT 阶段真实启动了应用，依赖本地服务 | 打包前起好服务，或 `NativeDetector.isNotAotRuntime()` 跳过（见 《native 约束与兼容性》） |
| `ClassNotFoundException: xxx`（native 运行时） | 类未被登记反射/未被包含 | 看 `target/classes/META-INF/native-image/.../reflect-config.json` 是否登记；没有则手动登记 |
| `MissingReflectionRegistrationError` | 反射调用目标类未登记 | 在 《native 项目开发定制》 的 Registrar 里补 `registerReflection` |
| `java.io.FileNotFoundException`（资源找不到） | 资源未登记 | 补 `registerResourceInclude` |
| `NoSuchMethodError` / `NoSuchFieldError`（native 运行时） | 方法/字段未登记 | 补 `registerMethod` / `registerField` 或对应 MemberCategory |
| 序列化抛 `InvalidClassException` / 反序列化失败 | 类未登记序列化 | 补 `registerSerialization`（方法参数/返回值会自动登记，见 《native 自动化处理清单》） |
| native 构建 OOM / 卡死 | 构建机内存不足 | 加内存或调整 native-image 构建参数 |
| native 构建失败：找不到 gcc/链接器 | 缺 OS 原生工具链 | 装 Xcode CLT / gcc+glibc-devel / VS Build Tools（见 《native 环境准备》） |
| AOT 阶段 `main` 抛业务异常导致打包中断 | 启动代码有问题 | 排查启动逻辑，或条件化跳过（同第 5 行） |
| 运行期 `ScanUtil` 扫不到资源 | 资源未进 solon-resource.json | 确认资源在 include 清单里，或用 `registerResourceInclude` 登记 |

### 2、标准排查流程

1. **确认 AOT 产物是否生成**：看 `target/classes/META-INF/native-image/<应用包路径>/` 下 5 个 json/properties 文件是否存在（《native 自动化处理清单》）。
2. **确认报错类是否已登记**：在 reflect-config.json / serialization-config.json / resource-config.json 里搜报错的类名或资源名。
3. **没登记 → 补登记**：在 `RuntimeNativeRegistrar` 实现里补对应 API（参考 《native RuntimeNativeRegistrar API 参考》），重新打包。
4. **已登记仍报错**：检查登记粒度是否够（比如只登记了 INTROSPECT 但需要 INVOKE；只登记了类但没登记字段/方法）。
5. **还不行**：看是否用了动态编译/字节码生成（A/B 类第三方库），考虑换库或换方案。

### 3、FAQ

* Q1：需要手动加 solon-aot 依赖吗？

不需要。`solon-parent` 的 `-P aot` / `-P native` profile 会自动引入 solon-aot 依赖并挂载 `process-aot` 插件。手动加依赖只在不用官方 profile 时才有意义。

* Q2：`-P aot` 和 `-P native` 有什么区别？

`-P aot`：执行 AOT 处理（生成代理源码 + 原生元数据），任意 JDK 可用；`-P native`：AOT 处理 + GraalVM 原生编译，需要 graalvm jdk17+，且启用官方可达性元数据仓库。

* Q3：为什么打包时我的 main 方法会被执行？

AOT 需要"真实启动"应用来收集容器信息，这是设计行为。启动副作用代码用 `NativeDetector.isNotAotRuntime()` 包裹即可。

* Q4：为什么 native 下 `Class.forName` 找不到类？

native 镜像只包含构建时可达的类。运行期动态加载的类不会进入镜像，需手动登记并确认该类被包含。

* Q5：native 镜像能跑 Java 序列化吗？

能，但序列化类必须登记（`registerSerialization`）。方法参数/返回值会自动登记，其余需手动。

* Q6：为什么 native 镜像比 JVM 包大 / 小？

native 只打包可达代码，通常更小；但大量反射登记（尤其 INVOKE）会增大镜像。按需登记、多用 INTROSPECT 少用 INVOKE 可控制体积。

* Q7：多模块项目 AOT 怎么处理？

只有主模块执行 AOT，其它模块常规构建。所有模块先 `mvn install`，主模块 AOT 时通过扩展加载机制合并各模块的 reflect-config.json / solon-resource.json（见 《aot 项目编译示范》）。

* Q8：第三方库支持情况怎么判断？

按 《native 项目开发定制》 的 A/B/C/D 分类：D 类（自带元数据）直接用；C 类补少量配置；B 类要实验调配置；A 类（动态编译/字节码）不支持。
