13 | 外部函数接口,能不能取代Java本地接口?
阅读案例
- 深入了解
- 翻译
- 解释
- 总结
Java的外部函数接口是一项新的孵化阶段特性,旨在解决Java本地接口(JNI)存在的安全性和跨平台性等问题。通过对比使用JNI和外部函数接口的代码,文章阐述了外部函数接口的优势,包括无需编写C代码、编译、链接生成C的动态库,避免了平台相关问题,并在安全性方面有所提升。外部函数接口可能会导致JNI退出,因为安全问题具有一票否决权。总的来说,外部函数接口为Java语言的生态环境带来了新的协作方案,未来可能需要逐步退出传统的基于JNI的解决方案。文章建议读者对外部函数接口有一个基本的印象,以便在未来的技术规划中考虑切换到外部函数接口。文章还提供了使用JShell快速学习新技术的方法,并鼓励读者在留言区分享阅读体验和代码设计。
《深入剖析 Java 新特性》,新⼈⾸单¥59
全部留言(11)
- 最新
- 精选
- JavaGuide另外,请问一下老师,这个提案https://openjdk.java.net/jeps/191中不是已经将Java 的外部函数接口这个特性的开发暂时停止了么?
作者回复: JEP 191被更好的方案取代了:https://openjdk.java.net/jeps/412
2021-12-222 - ABC在JDK18的JShell里面也试了一下,同样报错.
作者回复: JDK 18已经修复了,可能要等到下一个build才能见效。
2021-12-14 - ABC在JShell里面运行,发现报错: java.lang.IllegalCallerException:Illegal native access from: unnamed module @f2a0b8e 在OpenJDK的描述里面提示了,需要设置: java --enable-native-access=M 才能正确运行,但是JShell里面无法设置.老师,请问要怎么才能正常运行?谢谢.
作者回复: 使用“-R--enable-native-access=ALL-UNNAMED”的jshell命令行选项。
2021-12-142 - Jxin我的想法是,外部函数接口应该是现有RPC交互的一种暴露接口的新模式。就像暴露http接口,不同语言都暴露相同模式的“外部函数”接口,有一套跨语言的统一规则/协议。调用方与服务方皆遵循统一规则/协议交互。像现在这样,必须调用特定语言的调用规则,在泛化上走不通(要感知异构系统的语言),适用范围就会很局限。
作者回复: 还在孵化器,论证和构造原型为主。现在的设计,已经有点泛化的意思了。试图统一规则和协议的想法,最怕的就是一厢情愿,很难做成。
2021-12-14 - 小飞同学idea里面的–add-exports页面上一直没加上去,放弃了。jshell17.0.1执行结果,有遇到的小伙伴么?怎么解决的,java.lang.IllegalCallerException:Illegal native access from: unnamed module @6aa8ceb6 | at Reflection.ensureNativeAccess (Reflection.java:112) | at CLinker.getInstance (CLinker.java:131)
作者回复: 估计Github上的代码没有处理好编译/运行选项,应该设置“--enable-native-access=ALL-UNNAMED”参数。 workspace.xml: <option name="VM_PARAMETERS" value="--enable-preview --enable-native-access=ALL-UNNAMED --add-modules=jdk.incubator.vector,jdk.incubator.foreign" />
2021-12-143 - 小飞同学helloworld.c文件中没有写形参,gcc编译会报错。
作者回复: 谢谢,漏掉了。
2021-12-13 - kimoti外部函数借口是不是在内部编译,链接C语言程序,只不过这个过程对Java程序员透明而已?
作者回复: 应该是链接到C的动态库就行。
2021-12-13 - 学习感知不强,可能还需要时间来沉淀吧2021-12-132
- JavaGuideJNA 这个库貌似是目前的备用选择,JDK 官方也提到过这个库。 地址:https://github.com/java-native-access/jna2021-12-221
- ABCJShell运行: jshell --add-modules jdk.incubator.foreign -R--enable-native-access=ALL-UNNAMED import java.lang.invoke.MethodType; import java.lang.invoke.MethodHandle; import jdk.incubator.foreign.*; try (ResourceScope scope = ResourceScope.newConfinedScope()) { CLinker cLinker = CLinker.getInstance(); MemorySegment helloWorld = CLinker.toCString("Hello, world!\n", scope); MethodHandle cPrintf = cLinker.downcallHandle( CLinker.systemLookup().lookup("printf").get(), MethodType.methodType(int.class, MemoryAddress.class), FunctionDescriptor.of(CLinker.C_INT, CLinker.C_POINTER)); cPrintf.invoke(helloWorld.address()); }2021-12-1511