cooldatabase 发表于 2013-1-28 22:29:08

.通过JNI加载java虚拟机

前面已经分析了java命令加载java虚拟机的方法,即通过JNI和虚拟机交互。因此我们可以很容易的自己写相应的启动代码,实现在C++程序中执行java程序,调用java类的方法。

   要测试的Java类(Test.java)的代码是:

view plaincopy to clipboardprint?
public class Test {   
    public Test(){   
      System.out.println("Test's constructor");   
    }   

    public void sayHello(){   
      System.out.println("Test object say : Hello!");   
    }   

    public static int add(int arg1,int arg2){   
      return arg1 + arg2;   
    }   
      
    public static void main(String[] args) {   
      for (int i = 0; i < args.length; i++) {   
            System.out.println(args);   
      }   
    }   
}
public class Test {
    public Test(){
      System.out.println("Test's constructor");
    }

    public void sayHello(){
      System.out.println("Test object say : Hello!");
    }

    public static int add(int arg1,int arg2){
      return arg1 + arg2;
    }
   
    public static void main(String[] args) {
      for (int i = 0; i < args.length; i++) {
            System.out.println(args);
      }
    }
}




   加载jvm的C++(StartJVM.cpp)代码如下:

view plaincopy to clipboardprint?
/*
* startjvm.cpp
*
*Created on: 2010-1-28
*      Author: Xiutao Zang
*/
#include <iostream>   
#include <jni.h>   

using namespace std;   

int main()   
{   
    JavaVMOption options;   
    options.optionString = "-Djava.class.path=.";   
    JavaVMInitArgs args;   
    memset(&args, 0, sizeof(args));   
    args.version = JNI_VERSION_1_2;   
    args.nOptions = 1;   
    args.options = options;   
    args.ignoreUnrecognized = JNI_FALSE;   

    JNIEnv *env = 0;   
    JavaVM *vm = 0;   

    jint result = JNI_CreateJavaVM(&vm, (void **)&env, &args);   

    if (result == JNI_OK)   
    {   
      cout << "create the jvm successfully!" << endl;   
      jclass mainClass = env->FindClass("Test");   
      if (mainClass != 0)   
      {   
            cout << "find the main class successfully!" << endl;   

            jclass stringClass = env->FindClass("java/lang/String");   
            enum
            {   
                LENGTH = 2   
            };   
            const char *mainParams = { "Hello ", "World!" };   
            jstring jstringTemp;   
            jobjectArray mainArgs = env->NewObjectArray(LENGTH, stringClass, 0);   
            for (int i = 0; i < LENGTH; i++)   
            {   
                jstringTemp = env->NewStringUTF(mainParams);   
                env->SetObjectArrayElement(mainArgs, i, jstringTemp);   
            }   

            jmethodID mainID = env->GetStaticMethodID(mainClass, "main","([Ljava/lang/String;)V");   
            if (mainID != 0)   
            {   
                cout << "get main method successfully and invoke it!" << endl;   
                env->CallStaticVoidMethod(mainClass, mainID, mainArgs);   
            }   
            else
            {   
                cout << "get main method fail!" << endl;   
            }   

            jmethodID methodID = env->GetStaticMethodID(mainClass, "add", "(II)I");   
            if(methodID !=0){   
                int sum = env->CallStaticIntMethod(mainClass,methodID,4,6);   
                cout << "the result of Test.add(4,6) is : " << sum << endl;   
               }   

            methodID = env->GetMethodID(mainClass,"<init>","()V");   
            if(methodID != 0){   
                  jobject res = env->NewObject(mainClass,methodID);   
                  jmethodID objectMethodID = env->GetMethodID(mainClass,"sayHello","()V");   
                  if(objectMethodID != 0){   
                        env->CallVoidMethod(res,objectMethodID);   
                  }   
            }   
      }   
      else
      {   
            cout << "can't find main class!" << endl;   
      }   

      cout << "destroy the jvm!" << endl;   
      vm->DestroyJavaVM();   
      return 0;   
    }   
    else
    {   
      printf("create java jvm fail!\n");   
      return -1;   
    }   
}
/*
* startjvm.cpp
*
*Created on: 2010-1-28
*      Author: Xiutao Zang
*/
#include <iostream>
#include <jni.h>

using namespace std;

int main()
{
JavaVMOption options;
options.optionString = "-Djava.class.path=.";
JavaVMInitArgs args;
memset(&args, 0, sizeof(args));
args.version = JNI_VERSION_1_2;
args.nOptions = 1;
args.options = options;
args.ignoreUnrecognized = JNI_FALSE;

JNIEnv *env = 0;
JavaVM *vm = 0;

jint result = JNI_CreateJavaVM(&vm, (void **)&env, &args);

if (result == JNI_OK)
{
cout << "create the jvm successfully!" << endl;
jclass mainClass = env->FindClass("Test");
if (mainClass != 0)
{
cout << "find the main class successfully!" << endl;

jclass stringClass = env->FindClass("java/lang/String");
enum
{
LENGTH = 2
};
const char *mainParams = { "Hello ", "World!" };
jstring jstringTemp;
jobjectArray mainArgs = env->NewObjectArray(LENGTH, stringClass, 0);
for (int i = 0; i < LENGTH; i++)
{
jstringTemp = env->NewStringUTF(mainParams);
env->SetObjectArrayElement(mainArgs, i, jstringTemp);
}

jmethodID mainID = env->GetStaticMethodID(mainClass, "main","([Ljava/lang/String;)V");
if (mainID != 0)
{
cout << "get main method successfully and invoke it!" << endl;
env->CallStaticVoidMethod(mainClass, mainID, mainArgs);
}
else
{
cout << "get main method fail!" << endl;
}

jmethodID methodID = env->GetStaticMethodID(mainClass, "add", "(II)I");
if(methodID !=0){
    int sum = env->CallStaticIntMethod(mainClass,methodID,4,6);
    cout << "the result of Test.add(4,6) is : " << sum << endl;
   }

methodID = env->GetMethodID(mainClass,"<init>","()V");
if(methodID != 0){
jobject res = env->NewObject(mainClass,methodID);
jmethodID objectMethodID = env->GetMethodID(mainClass,"sayHello","()V");
if(objectMethodID != 0){
env->CallVoidMethod(res,objectMethodID);
}
}
}
else
{
cout << "can't find main class!" << endl;
}

cout << "destroy the jvm!" << endl;
vm->DestroyJavaVM();
return 0;
}
else
{
printf("create java jvm fail!\n");
return -1;
}
}





      我的运行环境是CentOS,AMD64平台。

相关环境变量:

export JAVA_HOME=/root/DevTools/jdk1.6.0_16
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=$CLASSPATH:.:$JAVA_HOME/lib:$JRE_HOME/lib
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH

export LD_LIBRARY_PATH=$JRE_HOME/lib/amd64/server:$JRE_HOME/lib/amd64



编译命令:

g++ -o StartJVM StartJVM.cpp -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux -L${JRE_HOME}/lib/amd64/server -ljvm



本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/ictzxt/archive/2010/01/28/5263750.aspx
页: [1]
查看完整版本: .通过JNI加载java虚拟机