Java 本地接口规范 (一)

2008-02-23 09:34:09来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

1 - 简介


本章介绍 Java 本地接口(Java Native Interface,JNI)。JNI 是本地编程接口。它使得在 Java 虚拟机 (VM) 内部运行的 Java 代码能够与用其它编程语言(如 C、C 和汇编语言)编写的应用程序和库进行互操作。

JNI 最重要的好处是它没有对底层 Java 虚拟机的实现施加任何限制。因此,Java 虚拟机厂商可以在不影响虚拟机其它部分的情况下添加对 JNI 的支持。程序员只需编写一种版本的本地应用程序或库,就能够与所有支持 JNI 的 Java 虚拟机协同工作。

本章论及以下主题:

  • Java 本地接口概述
  • 背景
  • 目标
  • Java 本地接口方法
  • 利用 JNI 编程
  • JDK 1.1.2 中的变化

Java 本地接口概述

尽管可以完全用 Java 编写应用程序,但是有时单独用 Java 不能满足应用程序的需要。程序员使用 JNI 来编写 Java 本地方法,可以处理那些不能完全用 Java 编写应用程序的情况。

以下示例说明了何时需要使用 Java 本地方法:

  • 标准 Java 类库不支持与平台相关的应用程序所需的功能。
  • 已经拥有了一个用另一种语言编写的库,而又希望通过 JNI 使 Java 代码能够访问该库。
  • 想用低级语言(如汇编语言)实现一小段时限代码。

通过用 JNI 编程,可以将本地方法用于:

  • 创建、检查及更新 Java 对象(包括数组和字符串)。
  • 调用 Java 方法。
  • 捕捉和抛出异常。
  • 加载类和获得类信息。
  • 执行运行时类型检查。

也可以与调用 API 一起使用 JNI,以允许任意本地应用程序嵌入到 Java 虚拟机中。这样使得程序员能够轻易地让已有应用程序支持 Java,而不必与虚拟机源代码相链接。


背景

目前,不同厂商的虚拟机提供了不同的本地方法接口。这些不同的接口使程序员不得不在给定平台上编写、维护和分发多种版本的本地方法库。

下面简要分析一下部分已有本地方法接口,例如:

  • JDK 1.0 本地方法接口
  • Netscape 的 Java 运行时接口
  • Microsoft 的原始本地接口和 Java/COM 接口


JDK 1.0 本地方法接口

JDK 1.0 附带有本地方法接口。遗憾的是,有两点原因使得该接口不适合于其它 Java 虚拟机。

第一,平台相关代码将 Java 对象中的域作为 C 结构的成员来进行访问。但是,Java 语言规范没有规定在内存中对象是如何布局的。如果 Java 虚拟机在内存中布局对象的方式有所不同,程序员就不得不重新编译本地方法库。

第二,JDK 1.0 的本地方法接口依赖于保守的垃圾收集器。例如,无限制地使用 unhand 宏使得有必要以保守方式扫描本地堆栈。


Java 运行时接口

Netscape 建议使用 Java 运行时接口 (JRI),它是 Java 虚拟机所提供服务的通用接口。JRI 的设计融入了可移植性---它几乎没有对底层 Java 虚拟机的实现细节作任何假设。JRI 提出了各种各样的问题,包括本地方法、调试、反射、嵌入(调用)等等。


原始本地接口和 Java/COM 接口

Microsoft Java 虚拟机支持两种本地方法接口。在低一级,它提供了高效的原始本地接口 (RNI)。RNI 提供了与 JDK 本地方法接口有高度源代码级的向后兼容性,尽管它们之间还有一个主要区别,即平台相关代码必须用 RNI 函数来与垃圾收集器进行显式的交互,而不是依赖于保守的垃圾收集。

在高一级,Microsoft 的 Java/COM 接口为 Java 虚拟机提供了与语言无关的标准二进制接口。Java 代码可以象使用 Java 对象一样来使用 COM 对象。Java 类也可以作为 COM 类显示给系统的其余部分。


目标

我们认为统一的,经过细致考虑的标准接口能够向每个用户提供以下好处:

  • 每个虚拟机厂商都可以支持更多的平台相关代码。
  • 工具构造器不必维护不同的本地方法接口。
  • 应用程序设计人员可以只编写一种版本的平台相关代码就能够在不同的虚拟机上运行。

获得标准本地方法接口的最佳途径是联合所有对 Java 虚拟机有兴趣的当事方。因此,我们在 Java 获得许可方之间组织了一系列研讨会,对设计统一的本地方法接口进行了讨论。从研讨会可以明确地看出标准本地方法接口必须满足以下要求:

  • 二进制兼容性 - 主要的目标是在给定平台上的所有 Java 虚拟机实现之间实现本地方法库的二进制兼容性。对于给定平台,程序员只需要维护一种版本的本地方法库。
  • 效率 - 若要支持时限代码,本地方法接口必须增加一点系统开销。所有已知的用于确保虚拟机无关性(因而具有二进制兼容性)的技术都会占用一定的系统开销。我们必须在效率与虚拟机无关性之间进行某种折衷。
  • 功能 - 接口必须显示足够的 Java 虚拟机内部情况以使本地方法能够完成有用的任务。

Java 本地接口方法

我们希望采用一种已有的方法作为标准接口,因为这样程序员(程序员不得不学习在不同虚拟机中的多种接口)的工作负担最轻。遗憾的是,已有解决方案中没有任何方案能够完全地满足我们的目标。

Netscape 的 JRI 最接近于我们所设想的可移植本地方法接口,因而我们采用它作为设计起点。熟悉 JRI 的读者将会注意到在 API 命名规则、方法和域 ID 的使用、局部和全局引用的使用,等等中的相似点。虽然我们进行了最大的努力,但是 JNI 并不具有对 JRI 的二进制兼容性,不过虚拟机既可以支持 JRI,又可以支持 JNI。

Microsoft 的 RNI 是对 JDK 1.0 的改进,因为它可以解决使用非保守的垃圾收集器的本地方法的问题。然而,RNI 不适合用作与虚拟机无关的本地方法接口。与 JDK 类似,RNI 本地方法将 Java 对象作为 C 结构来访问。这将导致两个问题:

  • RNI 将内部 Java 对象的布局暴露给了平台相关代码。
  • 将 Java 对象作为 C 结构直接进行访问使得不可能有效地加入“写屏障”,写屏障是高级的垃圾收集算法所必需的。

    标签:

    版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
    特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:GEF,EMF,RCP,Eclipse's plugin的几个问题(4) No more handles Ex

下一篇:GEF,EMF,RCP,Eclipse's plugin的几个问题(1) PackageNotFound Ex