常用的一些用于创建和初始化JVM的JNI函数

随着计算机技术的不断发展,多种编程语言之间的相互调用变得越来越常见,如 C++/C++、RPG、COBOL, 以及 Java 语言之间的相互调用。JNI(Java ">Native Interface,也称 java 本机接口)是一系列标准的 Java API。它支持 Java 语言和其它编程语言之间的相互调用。但是,JNI 是一把双刃剑,为开发人员带来极大的便利的同时也引入了潜在的威胁。如果使用不当,就会导致应用程序性能降低甚至整个应用程序都会崩溃。因此,如何正确有效的使用 JNI 技术变得越来越重要。

IBM i 将 Java 环境和 ILE(Integrated language environment)环境分离开来,java 不属于一种 ILE 语言,它不能被 bind 到 ILE 对象模型里去创建 program 或者 service program。要实现 java 和其他 ILE 语言之间的相互调用,就需要使用 JNI 提供的接口函数。

JNI 主要包含两大部分:Native methods 和 Java Invocation API。本文将重点介绍后者。

Native methods 是指通过非 java 语言实现的 java method,native method 可以访问一些系统级别的函数和 API,而这些函数是不能在 java 中直接调用的。但是,调用这些 API 会降低 Java 应用程序的可移植性。

Java Invocation API 提供了一系列接口函数,允许非 Java 代码创建和初始化 JVM\、加载 Class、调用 Java method 和销毁 JVM 等。Java 提供的这些接口函数可以使非 Java 多线程程序充分利用同一个 JVM 中的 java classes。

IBM i 上 Java Invocation API 主要提供给两类调用者:

ILE program 或者 service program, 这些程序需要支持 teraspace storage 模式。 IBM i PASE 可执行程序。

Java Invocation API

非 Java 程序要调用 Java 程序,必须首先创建 JVM,然后才能由 JVM 解释执行 class 文件。JNI 提供了一系列的接口函数,通过这些函数可以方便地创建和初始化 JVM。下面简单介绍常见的一些 Java 调用接口函数。

获得当前 job 已经创建的所
有的 JVM 函数: jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf,jsize bufLen,jsize *nVMs); 参数说明:vmBuf 是一个输出参数,存储指向 JavaVM 结构的指针,长度由参数 bugLen 决定。每一个 JVM
都有一个对应的 JavaVM 结构。nVMs 返回已经创建的 JVM 的数量,但 IBM i 上同一个 Job 只允许存在一个 JVM,因此 nVMs 的最大值是 1. 创建和初始化 JVM 函数: jint JNI_CreateJavaVM(JavaVM **p_vm,void **p_env,void *vm_args); 参数说明:p_vm 新创建的 JVM 指针,指向结构体 JavaVM, 其它的 JNI invocation API 会使用这个变量去识别 JVM。 p_env 新创建的 JVM 的 JNI 环境变量指针,它指向一个 JNI 函数表,贯穿于整个调用过程中,JNI 函数表中的函数调用都需要这个参数。vm_args 是一个结构体,包含 JVM 初始化的一些参数。当然,JVM 的参数有多种不同设置方式,本文不做具体介绍,更多相关信息,请参考(DW link) 注意: IBM i 上,同一个 job 或 process 里,Java 只允许同时存在一个 JVM。 销毁 JVM 函数: jint DestroyJavaVM(JavaVM *vm) 参数说明:vm 是指向要销毁的 JVM。 注意:在确认这个 JVM 已经不再被任何线程使用的情况下再去销毁 JVM。当 Job 结束的时候,JVM 会自动销毁,同时释放占用的资源并回收内存。 Attach 已经存在的 JVM 函数: jint AttachCurrentThread(JavaVM *vm,void **p_env,void *thr_args); 参数说明:vm 是表示某个 JVM 的 JavaVM 指针,它指向当前 thread 要 attach 到哪一个 JVM。p_env 当前 thread 的 JNI 环境指针。thr_args 包含 thread 特有的参数信息。 Detach 已经 attach 的 JVM 函数: jint DetachCurrentThread(JavaVM *vm); 参数说明: vm 是指向要 detach 的 JVM。

非 Java 程序如何创建和使用 JVM

在了解 Java 调用接口的基础上,要正确使用这些接口函数,还需要弄清楚非 Java 程序调用 Java 程序的基本步骤。下面是一个简单的步骤:

通过 JNI_CreateJavaVM() 创建 JVM 或者通过 AttachCurrentThread() attach 到已经存在的 JVM 上。 通过 JVM 找到想要运行的类 (class)。 找到类 (class) 中要调用函数的 methodID。 通过 methodID 调用这个函数。

在非 Java 程序中创建 JVM 有两种方法,一种是通过 JNI 调用来创建 JVM,另一种是由编程语言运行时环境帮助创建 JVM。当用户调用 java method 的时候,运行时环境会自动检测当前 job 有没有已经创建的 JVM,如果没有则调用 JNI_CreateJavaVM() 来创建 JVM,如果有则直接 attach 上去。RPG 语言运行时环境就提供了这种支持(详见"RPG call java"小节)。

IBM i 上,同一个 Job 只允许同时存在一个 JVM,因此 JNI_CreateJavaVM() 在同一个 job 中只能被成功的调用一次。如果当用户的应用程序需要调用 Java 方法的时候,当前 Job 没有已经创建的 JVM,那么需要显示(用户自己调用)或隐式(通过不同语言的 Runtime )的调用 JNI_CreateJavaVM() 来启动 JVM,这时当前 job 已经存在一个 JVM,如果其它的线程还需要调用 Java 方法,就不能再重新创建 JVM,只能调用 AttachCurrentThread() 去 attach 到当前 job 中的 JVM 上即可继续调用 Java 程序。

注意: 当用户创建 *PGM 或 *SRVPGM 的时候,QJVAJNI *SRVPGM 提供了 API 函数 JNI_CreateJavaVM() 的接口,该函数负责创建 JVM。 但是,QJVAJNI 没有初始化 API 函数 AttachCurrentThread() ,因此,像调用 JNI_CreateJavaVM() 一样调用 AttachCurrentThread() 会出错,这是通过 JNI 调用方式创建 JVM 时经常出现的一个问题。AttachCurrentThread() 函数需要通过 JavaVM 结构指针来调用,该结构存放在 QSYSINC 的 JNI 头文件里。下一小节会给出正确的调用示例。

时间: 2024-08-30 19:05:34

常用的一些用于创建和初始化JVM的JNI函数的相关文章

WordPress中用于创建以及获取侧边栏的PHP函数讲解_php技巧

register_sidebar()(创建侧边栏)建立一个侧边栏,用来放置小工具.这个函数使用的时候请放在一个函数里,挂载到 "widgets_init" 钩子. 用法 register_sidebar( $args ); 参数 $args (字符串 | 数组)(可选)要创建的侧边栏的参数. 默认值: $args = array( 'name' => __( 'Sidebar name', 'theme_text_domain' ), 'id' => 'unique-sid

JAVA中对象创建和初始化过程

分析一下JAVA中对象创建和初始化过程中涉及的相关概念问题,java中栈(stack)与堆(heap),对象.引用.句柄的概念. 1.Java中的数据类型 Java中有3个数据类型: 基本数据类型(在Java中,boolean.byte.short.int.long.char.float.double这八种是基本数据类型) 引用类型 null类型 其中,引用类型包括类类型(含数组).接口类型. 下列语句声明了一些变量: 以下是引用片段: int k ; A a; //a是A数据类型的对象变量名.

了解Backbone如何用于创建Ajax应用程序或单页界面

Backbone 是一个 http://www.aliyun.com/zixun/aggregation/33906.html">JavaScript 框架,可用于创建模型-视图-控制器 (model-view-controller, MVC) 类应用程序和单页界面.在本文中,我们将了解 Backbone 如何用于创建 Ajax 应用程序或单页界面. Web 应用程序越来越关注于前端,使用客户端脚本与 Ajax 进行交互.由于 JavaScript 应用程序越来越复杂,如果没有合适的工具和

C# 3.0新特征之创建和初始化集合对象

创建|对象|集合 一. 引言 C# 3.0中新的对象初始化器是一种简单的语法特征-借助于这种特征,对象的构建和初始化变得非常简单.假定你有一个类Student,它看起来有如下样子: public class Student{ public string firstName; public string lastName;} 那么,你可以使用对象初始化器来创建这个类的一个对象,如下所示: var student1 = new Student{firstName = "Bruce", la

Excel中四种常用类型图表的创建方法

Excel中四种常用类型图表的创建方法   上图中的四种不同类型的图表都是根据同一个表格创建的,也就是说,这四种常用的图表是没有特定的数据限制的. 一.创建柱形图 1.将光标定位到要创建图表的数据区域内,然后切换到"插入"选项卡,在"图表"组的"柱形图"下选择一种需要的柱形图类型进行创建. 2.现在工作表中已经插入了一个选择的柱形图. 二.创建条形图 1.将光标定位到表格区域内,然后选择一个合适的条形图类型进行创建. 2.现在工作表中已经插入了一

java中创建并初始化字符串方法

1.使用字符串常量直接初始化 String s="hello!"; 2.使用构造方法创建并初始化 String();//初始化一个对象,表示空字符序列 String(value);//利用已存在的字符串常量创建一个新的对象 String (char[] value);//利用一个字符数组创建一个字符串 String(char[] value,int offset,int count);//截取字符数组offset到count的字符创建一个非空串 String(StringBuffer

Go语言创建、初始化数组的常见方式汇总_Golang

本文实例总结了Go语言创建.初始化数组的常见方式.分享给大家供大家参考.具体分析如下: Go语言的语法很灵活,以下展示了创建并初始化数组的多种方式: 复制代码 代码如下: //数组初始化的各种方式  func arraySliceTest0201() {      //创建数组(声明长度)      var array1 = [5]int{1, 2, 3}      fmt.Printf("array1--- type:%T \n", array1)      rangeIntPrin

关于Java数组声明、创建、初始化的相关介绍_java

本文讲述了Java数组的几个相关的方面,讲述了对Java数组的声明.创建和初始化,并给出其对应的代码.一维数组的声明方式:type var[]; 或type[] var; 声明数组时不能指定其长度(数组中元素的个数), Java中使用关键字new创建数组对象,格式为:数组名 = new 数组元素的类型 [数组元素的个数] 实例:TestNew.java: 程序代码: public class TestNew { public static void main(String args[]) { i

sql server创建存储过程初始化失败,不知道为什么,求大侠帮忙看看

问题描述 sql server创建存储过程初始化失败,不知道为什么,求大侠帮忙看看 CREATE PROCEDURE p_getLogFilter @account VARCHAR(20), @split VARCHAR(10) AS BEGIN DECLARE @splitlen INT, @au_id CHAR(50), @s VARCHAR(MAX), @cform VARCHAR(255), @dbname VARCHAR(200), @sqlstr NVARCHAR(MAX) --获取