news 2026/9/25 5:12:26

JNA 版本演进全览:从 2.4 到 5.19 的变更日志深度解读

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JNA 版本演进全览:从 2.4 到 5.19 的变更日志深度解读
  • 系统编程
  • 后端

【免费下载链接】jna

Java Native Access

项目地址:https://gitcode.com/gh_mirrors/jn/jna
点击查看免费下载

本篇指南以 JNA(Java Native Access)官方仓库的 CHANGES.md 为核心骨架,系统梳理 JNA 从 2.4 到 5.19.0 十余年的版本演进脉络,并结合仓库源码(Platform.java、Native.java 等)解释关键变更背后的实现逻辑。读完本文,你将能够:快速定位某个能力(如 RISC-V 支持、JPMS 构件)在哪个版本引入、理解各版本"重要变化/破坏性变更"对升级的影响、掌握 JNA 运行时系统属性与平台适配机制,从而在升级 JNA 或排查原生库加载问题时做到心中有数。

一、先读两条总则:许可证与二进制兼容性

CHANGES.md开篇的两条 NOTE 是整个变更历史的"世界观",理解它们才能读懂后面所有版本记录。

  • 双许可证(自 4.0 起):JNA 4.0 之前是 LGPL 单一许可;4.0 起改为 LGPL 2.1 与 Apache License 2.0 双许可,开发者可自行选择适用协议,仓库根目录的 LICENSE、LGPL2.1、AL2.0 三份文件即对应这一安排。这一点在src/com/sun/jna/Version.java的版权头注释中也能看到:"dual-licensed under 2 alternative Open Source/Free licenses: LGPL 2.1 or later and Apache License 2.0 (starting with JNA version 4.0.0)"。
  • JNI 原生层的版本兼容性:JNI native 支持通常在小版本之间不兼容,大版本之间几乎总是不兼容。这意味着 JNA 的 Java 层与libjnidispatch原生库必须匹配。多个版本的记录直接印证了这一点,例如 5.14.0 明确写道"The interfaces between Java and native code have changed, solibjnidispatchmust be rebuilt to be compatible with this release",3.3.0 也注明该变更"incompatible with all previous JNA native libraries"。升级 JNA 时,如果自定义构建了原生库,必须同步重建。

二、版本节奏与"Next Release"

文档顶部保留了一个Next Release (5.20.0)的空骨架(Features 与 Bug Fixes 均未填充),说明这是一个仍在活跃开发的滚动变更日志。已发布版本从 5.19.0 一直回溯到 2.4,跨越 3.x、4.x、5.x 三个大版本代际。整体趋势清晰:

  • 2.x → 3.x:奠定基础能力(Unions、类型映射、libffi 多平台、直接映射雏形)。
  • 3.x → 4.x:引入 Apache 双许可、Java 6 默认级别、系统属性体系成型、platform模块(win32/unix/mac)大规模扩充。
  • 4.x → 5.x:JDK 8 起跳、finalizer 退出历史舞台、架构矩阵大幅扩张(RISC-V、LoongArch64、aarch64、DragonFlyBSD 等)、JPMS/OSGi 现代化、Android 16KB 页大小适配。

三、平台与 CPU 架构支持矩阵(最活跃的演进主线)

CHANGES.md中数量最多的条目类别就是"新增平台支持",这与 JNA 的本质——通过 libffi 桥接 Java 与任意平台原生代码——完全一致。仓库lib/native/目录下 40+ 个*-*.jar(如linux-loongarch64.jar、linux-riscv64.jar、freebsd-aarch64.jar、win32-aarch64.jar)就是这份支持矩阵的实物证据。

3.1 新架构的引入时间线

版本新增平台/架构
5.19.0OpenBSD 7.9 x86-64 重建,放弃 OpenBSD x86
5.18.0Platform#isRISCV()(Platform.java)
5.15.0FreeBSD aarch64、DragonFly BSD x86-64、linux-riscv64 进入 OSGi Bundle-NativeCode
5.14.0linux-riscv64 改在 Ubuntu focal 上构建以兼容更老的 glibc
5.12.0LoongArch64
5.8.0linux-riscv64 首度引入;macOSRESOURCE_PREFIX改为darwin-$arch
5.7.0macOS aarch64 纳入 universal darwin 目标;Windows aarch64
4.5.0linux-mips64el、linux-s390x
4.4.0armel(ARM EABI Little-endian),区分硬浮点与软浮点
4.2.1linux-sparcv9
4.2android aarch64 / x86-64 / mips / mips64
3.5.0android-arm
3.4.0linux/arm、linux/ppc、linux/ia64、linux/ppc64、w32ce-arm

3.2 源码中的架构归一化逻辑

CHANGES.md中"把 SAPJVM8 上报的zarch_64映射为s390x"这类看似琐碎的修复,在源码里对应Platform#getCanonicalArchitecture的归一化逻辑(Platform.java):i386/i686→x86、x86_64/amd64→x86-64、powerpc→ppc、zarch_64→s390x,并且会根据sun.cpu.endian把ppc64修正为ppc64le。软浮点检测则在ELFAnalyser中完成:3.5.0 的修复指出旧工具链产出的二进制缺少硬/软浮点标记(Raspbian、Oracle JDK 均受影响),因此判定逻辑同时参考 ARM EABI 段。Platform类因此暴露了isARM()、isLoongArch()、isRISCV()、isMIPS()、isPPC()等判定方法供上层使用。

3.3 平台识别:从常量到方法

Platform用一组整型常量标识 OS(Platform.java):MAC/LINUX/WINDOWS/SOLARIS/FREEBSD/OPENBSD/WINDOWSCE/AIX/ANDROID/GNU/KFREEBSD/NETBSD/DRAGONFLYBSD。5.15.0 中"DragonFlyBSD 纳入NativeLibrary版本化库解析、libc 特例加载和 64 位搜索路径"对应 Native.java 中isDragonFlyBSD()与 Linux/Solaris/AIX/FreeBSD 等并列的搜索分支。macOS 的darwin-$arch前缀变更(5.8.0 重要变化)也体现在Platform.RESOURCE_PREFIX = getNativeLibraryResourcePrefix()(Platform.java),旧前缀仍作为回退搜索位置。

四、JDK 与运行环境要求的变化

4.1 最低 JDK 的两次跃迁

  • 5.14.0:正式放弃 JDK 6 和 7,最低要求 JDK 8。
  • 5.18.0:新增文档说明"运行 JNA 需要 JDK 24+"(对最新发布版而言),同时修复了 Xcode 16.3 / Apple Clang 17 下的原生构建错误——这提醒我们:构建环境和运行环境是两条独立的要求线。

4.2 对 JDK 内部变化的适应

  • JDK 10(4.0 时代):javah被移除,改用javac -h生成头文件;构建最低要求升至 JDK 8,而运行时仍兼容 Java 6。
  • JEP 400 / JDK 18(5.10.0):file.encoding默认改为UTF-8,JNA 更新了原生编码检测逻辑以匹配。
  • SecurityManager(5.19.0):移除对java.lang.SecurityManager/java.security.AccessController的硬依赖。这也呼应了更早的 3.0.9/4.0 中"显式处理 Android 损坏的 SecurityManager 实现"等历史包袱。
  • 反射兼容(5.3.1):ReflectionUtils不再通过反射访问java.lang.invoke.MethodType,避免 Android API level < 26 时抛NoClassDefFoundError。

五、内存管理与对象生命周期的现代化

JNA 涉及大量跨 JNI 边界的原生内存,其生命周期管理策略是各版本反复打磨的重点:

  • 5.12.0(重要变化):Memory#dispose、CallbackReference#dispose、NativeLibrary#dispose原先由Object#finalize调用,现改为使用 Cleaner(java.lang.ref.Cleaner)。副作用是:不再保证子类 finalization 时一定调用dispose,开发者应显式管理资源。
  • 5.14.0:当最后一个 cleanable 被移除后关闭CleanerThread,避免线程泄漏。
  • 5.12.1:在Memory#close中对 cleanable 做 null 检查(Memory.java)。
  • 5.15.0:修复free_callback的 JNI weak reference 泄漏。
  • 5.8.0:确保从 Memory 间接得到的指针在解引用时保留其源对象引用,防止被 GC 提前回收——这类"防过早 GC"修复贯穿始终,如 4.3.0 中"将整个对象传入 JNI 调用以阻止 Pointer/Function 被提前回收"、3.1.0 中"存在直接 NIO Buffer 映射时确保 Memory 不被 GC"。

六、直接映射(Direct Mapping)与性能路线

JNA 提供两种调用模式:接口映射(interface mapping,动态代理)与直接映射(direct mapping,编译期生成桩代码)。CHANGES.md记录了直接映射能力的逐步完善:

  • 3.1.0:引入静态 Java 方法的原始 JNI 映射,文档明示其性能约为传统接口映射的10 倍,但类型转换功能较少。
  • 3.2.0:直接映射开始支持 String、Structure、Callback、Buffer、基本类型数组及 NativeMapped/TypeMapper(含 IntegerType、PointerType 的优化路径)。
  • 4.5.0:直接映射支持boolean[],并新增OPTION_ALLOW_OBJECTS选项。
  • 5.3.0:接口默认方法支持(实验性)。
  • 性能类改进还包括:5.7.0 提升Memory分配性能与Structure#read/write性能;5.16.0 为Structure增加字段列表缓存和可重入读写锁(替换synchronized);5.4.0 通过遍历可用构造函数而非异常处理提升Structure#newInstance;4.2 中Library$Handler/Function减少锁竞争与 varargs 检查。

七、关键系统属性与运行时配置(源码级印证)

CHANGES.md在多个版本散布介绍了运行时系统属性,这些属性在源码中都有直接对应,汇总如下(来源:Native.java、NativeLibrary.java、Structure.java、Platform.java):

系统属性作用引入/变化版本源码位置
jna.nosys是否加载系统预装 JNA(默认自 5.0.0 起为true,即默认用内嵌原生库)3.4.0 引入;5.0.0 改默认值;5.2.0 Android 特例Native.java
jna.boot.library.name覆盖jnidispatch原生库名3.4.0Native.java
jna.nounpack禁止解包内嵌原生库(Android 上由Platform自动置为 true)3.4.0Native.java、Platform.java
jna.debug_load打印库加载诊断4.0Native.java
jna.encoding自定义原生字符串编码(2.5 引入,默认随后续 JEP400 演进)2.5 引入;5.10.0 适配 JDK18Native.java
jna.library.path追加原生库搜索路径(3.2.7 起每次加载时重新评估)3.2.7NativeLibrary.java
jna.tmpdir覆盖临时解包目录(默认 macOS 为~/Library/Application Support/JNA/temp,其他 Unix 为$XDG_CACHE_DIR/JNA/temp,5.0.0 起)3.5.0 引入;5.0.0 改默认位置Native.java
jna.profiler.prefix自动剥离分析器前缀(默认$$YJP$$)4.0NativeLibrary.java
jna.dump_memoryStructure.toString是否输出原生内存转储4.0Structure.java

另有 5.0.0 引入的Library.OPTION_CLASSLOADER(允许从任意类加载器加载 JNA 原生库)、Library.OPTION_STRING_ENCODING(每库字符串编码,5.14.0 修复其被忽略的 bug)、Library.OPTION_OPEN_FLAGS(定制dlopen行为,3.5.0 引入)。

八、五个必须知道的"重要/破坏性变更"

CHANGES.md用专门小节标注了升级时可能破坏既有代码的变更,以下几项影响面最广:

8.1 5.0.0:一次大规模 API 清理

这是破坏性变更最密集的一个版本,主要包括:

  • Pointer#SIZE移除,改用Native#POINTER_SIZE(避免多线程初始化 JNA 时的类加载死锁)。
  • Pointer#getString(offset, wide)、setString(offset, value, wide)、getStringArray(offset, wide)移除,分别以getString/getWideString、setString/setWideString、getStringArray/getWideStringArray替代。
  • Structure#setFieldOrder移除,强制使用getFieldOrder()(对应 5.0.0 新增的@Structure.FieldOrder注解,可用注解声明字段顺序而无需实现getFieldOrder())。
  • Native#getDirectByteBuffer由Pointer#getByteBuffer取代;Platform#isAix改名为isAIX。
  • Win32 平台:SecBufferDesc按正确原生语义重写(多 buffer 描述原本是坏的,普通场景建议用SspiUtil.ManagedSecBufferDesc);FILETIME#toLong()改名toTime();COMException结构重构(移除pExcepInfo/puArgErr,新增hresult成员,细节迁至COMInvokeException);ACE_HEADER取代ACEStructure作为 ACE 基类,ACL#getACEStructures更名为getACEs并支持非 ACCESS_ALLOWED/DENIED 类型。
  • LoadTypeLib(WString, ...)、CLSIDFromString(WString, ...)改为 String 版本;MonitorFromPoint(Point, ...)改为Point.ByValue。

8.2 5.8.0:JPMS 构件坐标变更

实验性的 JPMS(Java 模块系统)构件从带jpmsclassifier 改为独立构件 ID:jna-jpms.jar与jna-platform-jpms.jar(不带 classifier)。原因是 platform 构件依赖 jna 构件,用 classifier 无法保证解析到正确变体。仓库根目录的 pom-jna-jpms.xml 与 pom-jna-platform-jpms.xml 即对应这两个模块。

8.3 5.7.0:darwin x86 预构建移除

32 位 Java on macOS(darwin x86)的预编译原生库被移除,这是唯一的"Breaking Change"。

8.4 5.12.0:finalizer 退出

见第五节,改用 Cleaner 后dispose不再保证在子类 finalization 时被调用。

8.5 5.14.0:varargs 上限与最低 JDK

varargs 调用支持的固定参数上限从 3 提升到255(对如printf类函数影响显著);同时最低 JDK 升至 8。此外 5.7.0 开始引入的module-info.class(jna-jpms.jar)在 5.8.0 完成坐标调整。

九、platform 模块(win32 / unix / mac)的持续扩充

JNA 的 platform 模块(contrib/platform/src/com/sun/jna/platform/)为各操作系统提供开箱即用的绑定,CHANGES.md中超过一半的条目属于此类。按主题归纳:

  • Win32 系统能力:注册表(RegLoadAppKey、RegNotifyChangeKeyValue、Advapi32Util多语言formatMessage)、进程与线程(CreateRemoteThread签名修正、GetProcessAffinityMask、Thread32First/Next、IsProcessorFeaturePresent)、文件与内存映射(OpenFileMapping、VirtualLock/VirtualUnlock)、安全(isCurrentProcessElevated、Crypt32Util敏感数据清理与零长度数组处理)、网络与蓝牙(5.19.0 新增WlanApi与BluetoothApis)、打印(Winspool的SetJob/SetPrinter与打印机通知)、电源与电池(5.17.0 电源事件、CallNTPowerInformation)、性能计数器(Pdh/PdhUtil系列)。
  • macOS:SystemB自 4.2 引入后持续扩展(进程/网络/文件系统信息、5.19.0 新增ProcFdInfo/InSockInfo/TcpSockInfo/proc_pidfdinfo/statfs64/vm_deallocate),5.19.0 还新增CoreGraphics绑定并实现MacWindowUtils#getAllWindows;XAttr/XAttrUtil的语义与 CLI 对齐(5.4.0)。
  • Unix/Linux:libc 封装(LibCAPI的size_t/ssize_t、statvfs/sysinfo)、libudev(UdevDevice#getSysname修复)、共享内存(LibRT的shm_open/shm_unlink)、X11 窗口操作(5.15.0 的XMoveWindow等)、BSDExtAttr(5.14.0)、CUPS 打印(5.19.0)。
  • COM/WMI:自 4.x 大规模建设,5.14.0 继续补充IWbemClassObject/IWbemServices的方法绑定;5.3.0 支持 COM setter 多参数与ProxyObject。

一个直观的佐证:5.19.0 新增的WlanApi就在仓库中(contrib/platform/src/com/sun/jna/platform/win32/WlanApi.java),以public interface WlanApi extends Library的标准 JNA 接口形式存在,同类的CoreGraphics、Cups、BluetoothApis均可在此目录下找到对应文件。

十、给升级者的实战建议

  1. 先看"Important Changes / Breaking Changes"小节:每次大版本升级前,重点排查这些标记段(5.0.0 最密集),尤其是被移除/改名的 API(如Pointer#getString(offset, wide)系列)与COMException结构变化。
  2. 原生库必须匹配:只要记录了"libjnidispatch需要重建"(3.3.0、5.14.0),自建原生库的团队就必须同步重建;即使使用官方 jar,也要保证 Java 层与原生层来自同一版本。
  3. 核对 JDK 基线:5.14.0 起需 JDK 8+;若使用最新发布版(5.18.0 起文档化要求 JDK 24+),请以官方发布说明为准。若需在旧 JDK 上运行,应停留在对应历史版本。
  4. 关注架构匹配:os.arch会被归一化(如zarch_64→s390x),软浮点 ARM 自动归为armel;若在 Android 上使用,注意 16KB 页大小修复(5.16.0/5.17.0)与jna.nounpack自动置 true 的机制。
  5. 善用诊断属性:库加载失败时设置jna.debug_load=true;需要自定义搜索路径时使用jna.library.path;临时目录可通过jna.tmpdir覆盖(默认已改为各平台的用户缓存目录)。
  6. 对象生命周期:5.12.0 起不再依赖 finalizer,涉及Memory/CallbackReference/NativeLibrary等资源时,请显式调用dispose()/close(),不要依赖 GC 兜底。

十一、进一步阅读

  • 变更日志全文:CHANGES.md(按版本回溯,2.4 至今)
  • 版本信息定义:src/com/sun/jna/Version.java(构建系统会替换TEMPLATE占位符)
  • 平台与架构判定:src/com/sun/jna/Platform.java
  • 库加载与系统属性:src/com/sun/jna/Native.java、src/com/sun/jna/NativeLibrary.java
  • 原生库构件清单:lib/native(各平台*.jar)
  • 平台模块源码:contrib/platform/src/com/sun/jna/platform
  • JPMS 相关 POM:pom-jna-jpms.xml、pom-jna-platform-jpms.xml

如需获取最新版本,可使用git clone该仓库后自行构建(构建说明见 README.md 与 common.xml),并在升级前反复对照本文梳理的各版本变更点。

  • 系统编程
  • 后端

【免费下载链接】jna

Java Native Access

项目地址:https://gitcode.com/gh_mirrors/jn/jna
点击查看免费下载
上一篇:MTR 开源项目使用教程
下一篇:如何使用Picturefill实现完美的响应式图片加载方案

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/25 5:11:36

ADAU1701音频DSP实战:从SigmaStudio到硬件设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/25 5:09:53

Atlas 300V 24G部署YOLO推理加速卡实战指南

先说结论&#xff1a;Atlas 300V 24G就是一张AI运算加速卡&#xff0c;而且是专为“推理”场景设计的加速卡。如果你手头有训练好的YOLO模型&#xff0c;想在边缘服务器或者机房里面把它跑起来&#xff0c;用这张卡做在线推理&#xff0c;那路子基本是对的。但这里有个很多人刚…

作者头像 李华
网站建设 2026/9/25 5:08:52

nanoGPT GPT 训练、复现与微调实操指南:10 分钟跑通最小闭环

nanoGPT GPT 训练、复现与微调实操指南&#xff1a;10 分钟跑通最小闭环 【免费下载链接】nanoGPT The simplest, fastest repository for training/finetuning medium-sized GPTs. 项目地址: https://gitcode.com/GitHub_Trending/na/nanoGPT nanoGPT 是目前最精简、最…

作者头像 李华