Java вызов JNI FindClass перестал работать из программы C++

Я пытаюсь следовать этому учебному руководству, которое называет класс Java из программы C++. Виртуальная машина Java инстанцируют, но вызов к сбоям FindClass. Пример кода непосредственно из учебного руководства:

Класс общественности MyTest.java MyTest {частный статический интервал magic_counter=777;

    public static void mymain() { 
       System.out.println("Hello, World in java from mymain");
       System.out.println(magic_counter);
    }
}

main.cpp

#include <jni.h>
#include <iostream>


using namespace std;
int main()
{
    JavaVM *jvm;
    JNIEnv *env;
    JavaVMInitArgs vm_args;
   JavaVMOption* options = new JavaVMOption[1];
   options[0].optionString = "-Djava.class.path=./";
   vm_args.version = JNI_VERSION_1_6;
   vm_args.nOptions = 1;
   vm_args.options
   = options;
   vm_args.ignoreUnrecognized = false;

   jint rc = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
   delete options;   
   if (rc != JNI_OK) {
         std::cin.get();
         exit(EXIT_FAILURE);
   }

   cout << "JVM load succeeded: Version ";
   jint ver = env->GetVersion();
   cout << ((ver>>16)&0x0f) << "."<<(ver&0x0f) << endl;

   jclass cls2 = env->FindClass("MyTest");  
   if(cls2 == nullptr) {
       cerr << "ERROR: class not found !";
   }
   else {
       cout << "Class MyTest found" << endl;
       jmethodID mid = env->GetStaticMethodID(cls2, "mymain", "()V");  
       if(mid == nullptr)
           cerr << "ERROR: method void mymain() not found !" << endl;
       else {
           env->CallStaticVoidMethod(cls2, mid);                      
           cout << endl;
       }
   }

   jvm->DestroyJavaVM();
   cin.get();
}

g ++ команда:

g++ -I/usr/lib/jvm/java-8-openjdk-amd64/include -I/usr/lib/jvm/java-8-openjdk-amd64/include/linux -L/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server  main.cpp -o SearchEngineCpp -ljvm

Я работаю javac SearchEngine.java создать файл класса.

Что я делаю неправильно?

0
задан 9 March 2020 в 03:14

1 ответ

Это может произойти, если у Вас есть несколько версий JDK в Вашей системе и версия Java по умолчанию для javac компилятор класса отличается от libjvm.so с которым Вы связываете свой исполняемый файл.

Например, в моих 18,04 системах:

$ update-alternatives --list javac
/usr/lib/jvm/java-11-openjdk-amd64/bin/javac
/usr/lib/jvm/java-8-openjdk-amd64/bin/javac

и

$ javac -version
javac 11.0.6

затем

$ javac MyTest.java
$
$ LD_LIBRARY_PATH=/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server ./SearchEngineCpp 
JVM load succeeded: Version 1.8
ERROR: class not found !

Можно работать вокруг этого путем вызова соответствующего компилятора Java явно напр.

$ /usr/lib/jvm/java-8-openjdk-amd64/bin/javac MyTest.java
$
$ LD_LIBRARY_PATH=/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server ./SearchEngineCpp 
JVM load succeeded: Version 1.8
Class MyTest found
Hello, World in java from mymain
777

Для персистентного решения в масштабе всей системы используйте update-alternatives механизм для выбора соответствующей версии Java:

sudo update-alternatives --config java
sudo update-alternatives --config javac
sudo update-alternatives --config javap
1
ответ дан 17 March 2020 в 00:06

Другие вопросы по тегам:

Похожие вопросы: