记录一下在linux环境下利用jni接口实现c++调用jar的过程
步骤1: 查看是否安装了c++程序gcc
步骤2:设置java环境
2.1 查看 java的安装路径
$ which java
/usr/bin/java
2.2 上述路径可能是软链接,通过如下方式查看java的实际安装路径
$ ls -al /usr/bin/java
lrwxrwxrwx 1 root root 22 8月 2 2021 /usr/bin/java -> /etc/alternatives/java
$ ls -al /etc/alternatives/java
lrwxrwxrwx 1 root root 46 8月 2 2021 /etc/alternatives/java -> /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java
上述显示结果说明 java的安装目录是 /usr/lib/jvm/java-8-openjdk-amd64
2.3 设置JAVA环境变量
$ vi /etc/profile
在文件末尾增加
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/jre/lib/rt.jar
export LD_LIBRARY_PATH=$JAVA_HOME/jre/lib/amd64/server/
并通过如下方式让环境变量生效
$ source /etc/profice
之后用如下方式编译 c++程序
$ g++ -o mytest mytest.cpp -I ${JAVA_HOME}/include -I ${JAVA_HOME}/include/linux -L ${JAVA_HOME}/jre/lib/amd64/server -ljvm
c++程序 示例
#include <stdio.h>
#include <iostream>
#include <jni.h>
#include <string.h>
using namespace std;
bool DebugDir_printInfo = true;
JNIEnv *env;
JavaVM *jvm;
bool startJVM(){
JavaVMOption options[2];
JavaVMInitArgs vm_args;
long status;
jclass cls;
jmethodID mid;
jint jsum;
jboolean jnot;
jobject jobj;
options[0].optionString = (char*)"-Djava.compiler=NONE";
options[1].optionString = (char*)"-Djava.class.path=.:anl.jar"; //在这里添加要使用的jar包
vm_args.version = JNI_VERSION_1_8;
vm_args.nOptions = 2;
vm_args.options = options;
vm_args.ignoreUnrecognized = JNI_TRUE;
status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
if (status != JNI_ERR) {
cout << "Succeeded creating JVM " << endl;
cls = env->FindClass("oa/OaOperation"); // 这里是jar包内Test类的具体路径
if (cls != 0) {
cout << "Succeeded finding target Java class" << endl;
// 调用构造函数创建对象
mid = env->GetMethodID(cls,"<init>","()V");
if (mid != 0) {
jobj = env->NewObject(cls, mid);
// 如果想要捕获异常,可以使用注释中的语句
/*if (env->ExceptionOccurred()) {
env->ExceptionDescribe();
env->ExceptionClear();
return 0;
}*/
cout << "Succeeded creating object using java constructor" << endl;
}
}
else{
fprintf(stderr, "FindClass failed\n");
}
}
else{
cout << "Failed creating JVM " << endl;
return -1;
}
}
bool closeJVM(){
jvm->DestroyJavaVM();
fprintf(stdout, "Java VM destory.\n");
return 0;
}
bool OaOperation_run(char *initPath,char *value, char *level, char *dati_str){
cout << "OaOperation_run start " << endl;
jclass cls = env->FindClass("oa/OaOperation"); // 这里是jar包内Test类的具体路径
if (cls != 0) {
cout << "Succeeded finding target Java class" << endl;
// 调用run函数
jmethodID mid2 = env->GetStaticMethodID(cls, "run","(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
cout << mid2 << endl;
if (mid2 != 0) {
cout << initPath << endl;
jstring str1 = env->NewStringUTF(initPath);
jstring str2 = env->NewStringUTF( value);
jstring str3 = env->NewStringUTF(level);
jstring str4 = env->NewStringUTF(dati_str);
env->CallStaticVoidMethod(cls, mid2,str1,str2,str3,str4);
}
else{
fprintf(stderr, "FindMethod failed\n");
}
}
else{
fprintf(stderr, "FindClass failed\n");
}
jvm->DestroyJavaVM();
fprintf(stdout, "Java VM destory.\n");
return 0;
}
int main(int argc, char* argv[])
{
startJVM();
cout<<argc<<endl;
if(argc == 1){
cout<<"请输入测试的模块参数,如pressure,dp03,hgt等"<<endl;
}
else if(argc ==2){
cout<<argv[1]<<endl;
if(!strcmp(argv[1],"pressure")){
if (DebugDir_printInfo)cout<<"开始运行测试程序"<<endl;
OaOperation_run("/home/kylin/anl/test_in_linux/objective_analysis_set.txt","pressure", "000", "2021092408");
if (DebugDir_printInfo)cout<<"测试程序运行完成\n————————————————————\n\n\n"<<endl;
}
}
closeJVM();
}