---
title: "native 项目开发定制"
---

关于第三方框架的情况：

| 分类 | 说明 | 例子 |
| --- | --- | --- |
| A：完全不支持 | 内部有动态编译或字节码生成 | 部分旧版 ORM / 模板引擎 |
| B：支持，但需实验后加很多配置 | 反射多、元数据缺失 | "mysql-connector-java:5.x" |
| C：支持，只需补少量配置 | 基本兼容，补点资源/反射 | "mysql-connector-java:8.x" |
| D：完全支持 | 自带 native-image 元信息配置 | 多数现代框架 |

> 判断方法：先用 《native 故障排查与 FAQ》 的标准流程试一遍——报错 → 查是否缺登记 → 能补就补（B/C），补不了就是 A 类。


### 1、何时需要定制

* 使用 B / C 类第三方框架时
* 自己项目中使用了：
  * 反射（`Class.forName`、`getMethod`、`getField` 等）
  * 自定义资源文件（不在自动清单内的，见 《native 自动化处理清单》）
  * Java 序列化（方法参数/返回值之外的类）

基本原则：

* 所有反射，需要声明登记
* 所有资源，需要声明登记
* 需要 Java 序列化的类，需要声明登记

这里讲的项目定制，全是基于 `RuntimeNativeRegistrar` 接口完成上面这些事情（API 参考见 《native RuntimeNativeRegistrar API 参考》）。

```java
public interface RuntimeNativeRegistrar {
    void register(AppContext context, RuntimeNativeMetadata metadata);
}

```

### 2、定制示例 [demo4013-wood_native](https://gitee.com/noear/solon-examples/tree/main/4.Solon-Data/demo4013-wood_native) ：

这个示例，只需要增加 "mysql-connector-java:8.x" 的资源登记：

```java
@Component
public class RuntimeNativeRegistrarImpl implements RuntimeNativeRegistrar {
    @Override
    public void register(AppContext context, RuntimeNativeMetadata metadata) {
        metadata.registerResourceInclude("com.mysql.jdbc.LocalizedErrorMessages.properties");
      
    }
}
```

### 3、定制示例 nginxWebUI ：

这个示例就复杂一些，是已有项目改造过来，大约花费了大半天：

```java
@Component
public class RuntimeNativeRegistrarImpl implements RuntimeNativeRegistrar {
    @Override
    public void register(AppContext context, RuntimeNativeMetadata metadata) {
        metadata.registerResourceInclude("acme.zip");
        metadata.registerResourceInclude("banner.txt");
        metadata.registerResourceInclude("mime.types");
        metadata.registerResourceInclude("nginx.conf");

        metadata.registerResourceInclude("messages_en_US.properties");
        metadata.registerResourceInclude("messages.properties");

        metadata.registerSerialization(JSONConverter.class);
        metadata.registerSerialization(AsycPack.class);
        metadata.registerSerialization(JsonResult.class);
        metadata.registerSerialization(Server.class.getPackage());

        metadata.registerReflection(ProviderFactory.class,  MemberCategory.INVOKE_DECLARED_METHODS);
        metadata.registerReflection(BufferedImage.class,  MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
                MemberCategory.INVOKE_DECLARED_METHODS);
        metadata.registerReflection(JSONConverter.class, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
                MemberCategory.INVOKE_DECLARED_METHODS);

    }
}
```



### 4、序列化登记提醒

* **方法参数 / 返回值类型**（非 java.* 且实现 Serializable）会被 AOT **自动登记序列化**，无需手动；
* 其它需要 Java 序列化的类（如实体缓存、会话对象）需手动 `registerSerialization`；
* lambda 序列化需手动 `registerLambdaSerialization`。

详见 《native 自动化处理清单》。