Solon v4.0.5

native 项目开发定制

</> markdown
2026年8月12日 上午11:29:41

关于第三方框架的情况:

分类说明例子
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.forNamegetMethodgetField 等)
    • 自定义资源文件(不在自动清单内的,见 《native 自动化处理清单》)
    • Java 序列化(方法参数/返回值之外的类)

基本原则:

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

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

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

2、定制示例 demo4013-wood_native

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

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

3、定制示例 nginxWebUI :

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

@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 自动化处理清单》。