dreamlike-ocean / PanamaUring

使用panama api为java提供io_uring的绑定而无需使用jni绑定,同时统一文件IO和网络IO的模型,提供一套易用的异步IO API
MIT License
77 stars 12 forks source link

native-image适配 #38

Closed dreamlike-ocean closed 7 months ago

dreamlike-ocean commented 8 months ago

目前进度 首先对于生成器修改了LambdaMetaFactory和invokeDynamic的策略,通过系统变量native-mode控制 修改类似于

 MethodHandle methodHandle = MethodHandles.lookup().findConstructor(aClass, MethodType.methodType(void.class));
            if (use_lmf) {
                return NativeGeneratorHelper.ctorBinder(methodHandle);
            }
            return () -> {
                var mh = methodHandle.asType(methodHandle.type().changeReturnType(Object.class));
                try {
                    return (Object) mh.invokeExact();
                } catch (Throwable t) {
                    t.printStackTrace();
                }
                return null;
            };

已经成功native-image,但是存在大量的手动成分,一次构建需要如下指令

  1. mvn clean package -am -pl graal-native-example 生成fat-jar
  2. java -agentlib:native-image-agent=config-output-dir=./graal-native-example/src/main/resources/META-INF/nat ive-image,experimental-class-define-support 生成反射文件和预定义文件
  3. mvn clean package -am -pl graal-native-example 再次打包将上一步的文件打进去
  4. jar -uf ../graal-native-example/target/graal-native-example-fat.jar 。。。 将第二步生成的代理对应的字节码注入jar
  5. native-image --features=top.dreamlike.PanamaFeature --enable-native-access=ALL-UNNAMED --no-fallback --enable-preview -O3 --gc=G1 -march=native --initialize -at-build-time=top.dreamlike.panama.genertor.proxy.NativeCallGenerator -jar graal-native-example/target/graal-native-example-fat.jar 正式打包native-image

目前来看注入字节码这一步可以支持自动化,其他看起来无法省略 这里还有个问题是PanamaFeature的自动化,这个也很麻烦

dreamlike-ocean commented 8 months ago

进度更新 目前支持自动配置运行时初始化的类,啊,这里是指的这个当前这个库对应的初始化 提供

 @Override
    public void duringSetup(DuringSetupAccess access) {
        //getpid
        NativeImageHelper.initPanamaFeature(StdLib.class);
    }

这种方式帮助搞定Feature

dreamlike-ocean commented 7 months ago

1,目前使用Feature提供Panama api注册,该方案不变 2,对于反射,通过提供配置文件和Feature里面强制初始化某些类完成本库的适配,对于编译期生成的绑定则是通过apt生成配置文件完成 3,目前还存在一个问题,bytebuddy中依赖的字节码生成的proxy,这里可以通过predefined class功能支持,这个功能原理在于native模型下劫持define方法计算byte[]摘要再读取预先放置的classdata文件,这里存在一个问题我目前放置的prefined class是jdk21的字节码,如果运行时生成的不为jdk21就会使得字节码中的classversion改变生成数据的摘要,进而启动失败

dreamlike-ocean commented 7 months ago

尝试固定bytebuddy生成的proxy的java字节码版本到jdk5 这一就可以直接将prefined classes打包进文件参与graal构建,这做到了graalvm版本无关性且能保证native和jvm一致性,进而不需要用户重跑java agent生成 https://github.com/raphw/byte-buddy/pull/1586

dreamlike-ocean commented 7 months ago

目前进度https://github.com/dreamlike-ocean/PanamaUring/commit/c24131467d86a6c295895431786e80e8905a1217 选择是覆盖对应类的实现 如果对应pr可以合入直接使用新版本即可,目前先使用覆盖的方式吧