应用程序嵌入JVM使用

4次阅读

共计 1348 个字符,预计需要花费 4 分钟才能阅读完成。

有时候我们会想 jvm 和程序在同一进程中,和 jvm 交互或者做一些定制工作,需要把 jvm 嵌入到程序中。简单来说过程可以分为三步:初始化 jvm/ 执行 java 字节码 / 退出 jvm

初始化 jvm

加载 libjvm.so 到进程中并且调用 JNI_CreateJavaVm

    JNI_CreateJavaVM(JavaVM **vm, void **penv, JavaVMOption* options)

options 我们按照 launcher 中的设置就好,包含了 classpath/command/pid

    pid_t pid = getpid();
    char *op_pid = NEW_STRING(256);
    sprintf(op_pid,"-Dsun.java.launcher.pid=%d",pid);

    options[op_count++].optionString = "-Djava.class.path=.";
    if(class_path != nullptr && strcmp(class_path,".") != 0){char *op_class_path = NEW_STRING(strlen(class_path)+50);
        sprintf(op_class_path,"-Djava.class.path=%s",class_path);
        options[op_count++].optionString = op_class_path;
    }
    options[op_count++].optionString = "-Dsun.java.command=test_jvm";
    options[op_count++].optionString = "-Dsun.java.launcher=SUN_STANDARD";
    options[op_count++].optionString = op_pid;

退出 jvm

 if(vm->DetachCurrentThread() != JNI_OK || vm->DestroyJavaVM() != JNI_OK){return -1;}

执行 java 字节码

    JavaVM *vm = init_jvm(".:shen.jar");
    JNIEnv *env = get_jni_env();
    if(vm == nullptr || env == nullptr)
        return -1;

    jclass cla = env->FindClass("test");

    jmethodID method = env->GetStaticMethodID(cla,"main","([Ljava/lang/String;)V");

    jclass cla_string = env->FindClass("java/lang/String");

    jobjectArray args = env->NewObjectArray(1,cla_string, nullptr);

    char *cwd = NEW_STRING(256);
    getcwd(cwd,256);
    env->SetObjectArrayElement(args,0,env->NewStringUTF(cwd));

    env->CallStaticObjectMethod(cla,method,args);


    destroy_jvm();

本文代码

jvm_helper.cpp

正文完
 0