频道直达 - 专题 - 新闻 - 技巧 - 组网 - 开发 - 安全 - web编程 - 图像 - 操作系统 - 数据库 - 教育 - 旅游 - 健康 - 时尚 - 驱动 - 软件 - 游戏 - 多媒体 - ERP - 讨论组

将Java程序转换为Windows服务

来源: 作者:IT168 seasky 出处:巧巧读书 2008-02-06 进入讨论组
访问 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如下:
 
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的过程:
 
1. 装载JVM Dll。
2. 建立一个JVM。
3. 装载指定的Java类。
4. 调用main方法,也就是public static void main (String[] args)。

我们可以使用在jni.h中定义的JNI_CreateJavaVM方法来建立一个JVM实例。我们可
以在JDK的安装目录中找到jni.h。
 
    下面是一个简单的Java程序,在控制台中打印出"Hello World"。

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规范得到更多的细节。本文不再详细描述。
更多文章 更多内容请看Windows操作系统安装Windows权限设置Java环境安装配置专题,或进入讨论组讨论。
收藏此文】【 】【打印】【关闭
相关图文阅读
频道图文推荐
健 康 咨 询
时 尚 咨 询
巧巧读书宗旨
相关专题
讨论组问题推荐
站内各频道最新更新文档
站内最新制作专题
热门关键字导读
Photoshop教 程照片处理 照片制作 PS快捷键 抠图
计 算 机 故 障XP系统修复
艺 术 与 设 计设计 流媒体 设计欣赏 边框
计 算 机 安 全ARP
站内频道文章精选
巧巧电脑频道编辑信箱  告诉我们您想看的专题或文章