`

.通过JNI加载java虚拟机

    博客分类:
  • jvm
阅读更多
前面已经分析了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[i]);  
        }  
    }  

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[i]);
        }
    }
}




   加载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[1];  
    options[0].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[LENGTH] = { "Hello ", "World!" };  
            jstring jstringTemp;  
            jobjectArray mainArgs = env->NewObjectArray(LENGTH, stringClass, 0);  
            for (int i = 0; i < LENGTH; i++)  
            {  
                jstringTemp = env->NewStringUTF(mainParams[i]);  
                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[1];
options[0].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[LENGTH] = { "Hello ", "World!" };
jstring jstringTemp;
jobjectArray mainArgs = env->NewObjectArray(LENGTH, stringClass, 0);
for (int i = 0; i < LENGTH; i++)
{
jstringTemp = env->NewStringUTF(mainParams[i]);
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
分享到:
评论

相关推荐

    使用C++创建java虚拟机JVM,使用JNI调用java函数.zip

    本文将深入探讨如何使用C++创建Java虚拟机(JVM),并通过JNI来调用Java函数。这是一项技术性很强的任务,需要对C++编程、Java虚拟机的工作原理以及JNI接口有深入的理解。 首先,Java虚拟机(JVM)是Java平台的核心...

    深入JAVA虚拟机第二版 Bill Venners著 曹晓钢 蒋靖译

    通过学习《深入JAVA虚拟机第二版》,开发者可以提升对JVM的深入理解,从而更好地设计和优化Java程序,解决性能问题,提升应用程序的稳定性和效率。对于任何想要成为Java技术专家的人来说,这本书无疑是一本不可多得...

    JNI的两个头文件jni.h和jni_md.h

    5. **加载本地库**:在Java代码中使用`System.loadLibrary`加载本地库,使Java虚拟机能够找到并调用本地方法。 值得注意的是,JNI虽然强大,但也有其局限性和潜在的问题。例如,由于涉及到本地代码,调试起来可能...

    Java虚拟机规范.rar

    Java虚拟机(JVM,Java Virtual Machine)是Java平台的核心组成部分,它负责执行Java程序,为应用程序提供了一个抽象...通过阅读《Java虚拟机规范》这份文档,可以深入了解JVM的细节,从而更好地利用Java平台进行开发。

    Java虚拟机规范SE8版

    Java虚拟机规范SE8版是Oracle公司发布的Java平台标准版(Java SE)8的JVM官方指南,它定义了JVM如何执行Java字节码、内存管理、类加载机制以及各种与平台无关的特性。这个规范对于开发者、性能优化专家和Java平台的...

    JAVA通过JNI调用C#dll的整个项目工程

    JNI为Java开发者提供了一种方式来编写本地代码,这些本地代码可以与Java虚拟机(JVM)交互。JNI接口包括一系列的函数,如`FindClass`, `GetFieldID`, `CallVoidMethod`等,它们用于在Java和本地代码之间建立桥梁。 ...

    Delphi10.3 中通过JNI调用 Java 函数

    JNI的核心是Java虚拟机(JVM)和本地方法接口。当Java代码调用本地方法时,JVM会通过JNI接口找到相应的本地代码,并执行该代码。在Delphi中,我们需要编写C或C++的动态链接库(DLL),这个DLL将作为Delphi和Java之间...

    JNI攻略之十一――启动虚拟机调用java类

    标题与描述均指向了一个具体的技术主题——通过JNI(Java Native Interface)在C语言环境中启动Java虚拟机并调用Java类。这一技术应用广泛,尤其是在需要跨语言编程或利用Java的特性(如垃圾回收、多线程)而底层...

    深入JAVA虚拟机 不那么完美的第二版.pdf.zip

    《深入JAVA虚拟机 不那么完美的第二版》这本书虽然在印刷上可能存在一些小瑕疵,但这并不影响我们从中汲取宝贵的Java虚拟机(JVM)知识。Java虚拟机是Java平台的核心组成部分,它负责执行Java程序,提供了跨平台的...

    安卓的JAVA虚拟机 简单实用

    **安卓的JAVA虚拟机:简单实用** 在移动操作系统领域,Android以其开源、灵活的特性深受开发者喜爱。在Android系统中,Java...通过理解JAVA虚拟机的工作原理和优化技巧,开发者能够更好地构建高质量的Android应用。

    jni.h头文件

    通过这个结构体,本地方法可以访问和操作Java虚拟机(JVM)的各种服务。 5. **异常处理**:JNI提供了处理和抛出Java异常的机制,如`ExceptionOccurred`, `ExceptionDescribe`, `ExceptionClear`等。 `jni_md.h`...

    visual studio 2019下C++通过JNI调用JAVA代码

    如果在C++中运行,可能需要通过JNI的`AttachCurrentThread`等函数手动管理Java虚拟机(JVM)的生命周期。 总的来说,通过JNI,C++和Java代码可以相互调用,提供了一种灵活的跨语言通信机制。在Visual Studio 2019中...

    JAVA虚拟机(JVM)规范(中文版).rar

    **JAVA虚拟机(JVM)规范** JAVA虚拟机(JVM)是Java语言的核心组成部分,它为Java程序提供了运行环境,使得Java代码能在任何支持JVM的平台上运行,实现了“一次编写,到处运行”的目标。JVM规范定义了Java程序如何...

    java虚拟机学习

    Java虚拟机(JVM)是...通过对这些Java虚拟机的关键知识点的理解和实践,开发者能更好地编写高性能、可扩展的Java应用,并解决内存管理和并发等问题。通过阅读经典书籍,你可以深入学习JVM的内部机制,提升编程技能。

    Java虚拟机规范 深入java虚拟机

    它详细阐述了Java虚拟机(JVM)的工作原理,包括内存管理、类加载机制、字节码执行以及垃圾回收等核心概念。深入理解这些知识点对于提升程序性能、解决运行时问题以及设计高效的应用程序至关重要。 1. **JVM架构** ...

    JAVA虚拟机解读入门

    通过学习《JAVA虚拟机解读入门》,你将能够了解JVM如何加载和解析类,以及类加载的双亲委托模型。你还将掌握栈帧的工作方式,理解方法调用和返回的过程。此外,书中还会详细介绍垃圾收集的工作原理,包括如何判断...

    JNI.zip_java jni_jni

    1. **本地方法接口(JNI Interface)**:JNI定义了一组函数,这些函数由Java虚拟机(JVM)提供,用于Java代码调用本地(非Java)代码和本地代码调用Java代码。这些函数包括初始化本地方法、注册本地方法、调用Java...

    JNI.rar_java jni_jni

    通过`JNIEnv*`指针,你可以访问Java虚拟机(JVM)提供的服务,如调用Java方法,创建Java对象,访问字段等。 `Frame1.java`文件是Java源代码,它会包含JNI的使用。在这个文件中,你会看到一个Java类,其中定义了一个...

    jvm.rar_JAVA虚拟机_jvm

    JAVA虚拟机(JVM)是Java程序运行的核心组件,它是一种抽象计算机,负责解释和执行Java字节码,使得Java程序具有跨平台的能力。在深入理解JVM之前,我们需要了解几个基本概念: 1. **字节码**:Java源代码经过编译...

    jni.rar_JNI编程_java jni_jni_site:www.pudn.com

    JNI是一种规范,定义了Java虚拟机(JVM)如何与本地代码(非Java)交互。这种交互包括加载本地库、调用本地方法、传递数据等。JNI提供了丰富的API,使得Java程序员可以方便地在Java程序中嵌入本地代码。 2. **JNI...

Global site tag (gtag.js) - Google Analytics