访问 http://www.qqread.com/java/2008/02/h396353.html二、使用JVM API模拟Java运行时
由于Windows任务管理器将所有的Java进程都显示为"Java",因此,我们根本无法通过这种方式区分某一个Java进程。为了给每一个Java应用程序指定一个特殊的名子。我们需要使用JVM API来模拟Java运行时。
下面先来看看Java运行时(也就是java.exe)在运行时需要些什么。当我们使用java <类名>来运行java程序时,java.exe从系统路径动态装载了一些DLL库。这些Dll如下:
我们可以使用在jni.h中定义的JNI_CreateJavaVM方法来建立一个JVM实例。我们可
下面是一个简单的Java程序,在控制台中打印出"Hello World"。
更多内容请看Windows操作系统安装、Windows权限设置、Java环境安装配置专题,或进入讨论组讨论。
由于Windows任务管理器将所有的Java进程都显示为"Java",因此,我们根本无法通过这种方式区分某一个Java进程。为了给每一个Java应用程序指定一个特殊的名子。我们需要使用JVM API来模拟Java运行时。
下面先来看看Java运行时(也就是java.exe)在运行时需要些什么。当我们使用java <类名>来运行java程序时,java.exe从系统路径动态装载了一些DLL库。这些Dll如下:
1. java\jdk\jre\bin\client\jvm.dll
这个dll提供了JVM所需要的API。一但我们建立了一个JVM,jvm.dll就会依次装载所需的Dll,这些Dll如下:
2. java\jdk\jre\bin\hpi.dll
3. java\jdk\jre\bin\verify.dll
4. java\jdk\jre\bin\java.dll
5. java\jdk\jre\bin\zip.dll
下面是java.exe如何处理Dll的过程:
下面是java.exe如何处理Dll的过程:
1. 装载JVM Dll。
2. 建立一个JVM。
3. 装载指定的Java类。
4. 调用main方法,也就是public static void main (String[] args)。
3. 装载指定的Java类。
4. 调用main方法,也就是public static void main (String[] args)。
我们可以使用在jni.h中定义的JNI_CreateJavaVM方法来建立一个JVM实例。我们可
以在JDK的安装目录中找到jni.h。
package com.test; public class Hello{ public static void main(String[] args) { System.out.println("Hello World"); } }
下面是使用JNI来模拟java.exe的例子代码。在这里我们使用动态装载jvm.dll方法,而不是静态绑定jvm.lib。这样会更有弹性,如可以自由地选择java的版本。代码如下:
int InvokeMain() {
JavaVM *vm;
JavaVMInitArgs vm_args;
JavaVMOption options[1];
jint res;
JNIEnv *env;
jclass cls;
jmethodID mid;
options[0].optionString = CLASS_PATH;
vm_args.version = JNI_VERSION_1_4; // 设置JDK的版本
vm_args.options = options;
vm_args.nOptions = 1;
vm_args.ignoreUnrecognized = JNI_FALSE;
//装载jvm.dll
HINSTANCE handle = LoadLibrary(RUNTIME_DLL);
if( handle == 0) {
printf("Failed to load jvm dll %s\n",
RUNTIME_DLL);
return -1;
}
// 得到JNI_CreateJVM指针
createJVM = (CreateJavaVM)GetProcAddress(handle,
"JNI_CreateJavaVM");
res = createJVM(&vm, (void **)&env, &vm_args);
if (res < 0) {
printf("Error creating JVM");
return -1;
}
// 装载指定的类
cls = env->FindClass(CLASS_NAME);
if(cls == 0) {
printf("Exception in thread \"main\"
java.lang.NoClassDefFoundError: %s\n",
CLASS_NAME);
return -1;
}
//得到main方法
mid = env->GetStaticMethodID(cls, "main",
"([Ljava/lang/String;)V");
if(mid == 0) {
printf("Exception in thread \"main\"
java.lang.NoSuchMethodError: main\n");
return -1;
}
// 调用main方法(不传递参数)
env->CallStaticVoidMethod(cls, mid, 0);
// 如果程序抛出异常,打印它
if(env->ExceptionCheck()) {
env->ExceptionDescribe();
return -1;
}
return 0;
}
在装载com.test.Hello时,我们必须使用"/"分割符(如com/test/Hello)。还有我们需要理解JNI调用Java方法的格式。如,为了调用void main(String[] args)方法,格式为:([Ljava/lang/String;)V:,"["表示数组;"L<classname>;"描述一个Java对象,V表示这个方法返回void。我们可以从JNI规范得到更多的细节。本文不再详细描述。
在装载com.test.Hello时,我们必须使用"/"分割符(如com/test/Hello)。还有我们需要理解JNI调用Java方法的格式。如,为了调用void main(String[] args)方法,格式为:([Ljava/lang/String;)V:,"["表示数组;"L<classname>;"描述一个Java对象,V表示这个方法返回void。我们可以从JNI规范得到更多的细节。本文不再详细描述。
相关图文阅读
频道图文推荐
健 康 咨 询
时 尚 咨 询
相关专题
- Windows操作系统安装 (15618篇文章)
- Windows权限设置 (10238篇文章)
- Java环境安装配置 (5640篇文章)
- Windows操作系统安全集 (18679篇文章)
- Java编程开发手册 (8291篇文章)
- Windows频道 (9812篇文章)
- 系统服务 (612篇文章)
- J2SE综合:浅谈java程序发布之 jre 篇 (11次浏览)
- JAVA代码中使用魔法数值 (8次浏览)
- Hibernate缓存管理 (6次浏览)
- JAVA代码应该流畅和结构化 (5次浏览)
- Java JVM设置对性能的影响 (4次浏览)
- 开发框架:深入了解 Struts Validator (3次浏览)
- Java中的通信机制及与C/C API的集成 (1次浏览)
- 用Hibernate实现领域对象的自定义字段 (1次浏览)
- Java语言入门 简述Java语言回收机制 (0次浏览)
- 2008年Java开发者最迫切的五个期望 (0次浏览)



