有時候咱們會想jvm和程序在同一進程中,和jvm交互或者作一些定製工做,須要把jvm嵌入到程序中。簡單來講過程能夠分爲三步:初始化jvm/執行java字節碼/退出jvmjava
加載libjvm.so到進程中而且調用JNI_CreateJavaVm git
JNI_CreateJavaVM(JavaVM **vm, void **penv, JavaVMOption* options)
options咱們按照launcher中的設置就好,包含了classpath/command/pidgithub
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;
if(vm->DetachCurrentThread() != JNI_OK || vm->DestroyJavaVM() != JNI_OK){ return -1; }
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();