JNI calling Java from C++ with multiple threads

10

I'm working on a project, where I call Java functions from C++ code (using JNI) and I have a problem about multithreading. I want to call Java searching function and for each call I want to make a separate thread. I have a singleton MainClass and nested Query class. Query class is inherited from QThread. Code looks like this

MainClass::MyQuery query("<some search query>");
query.LaunchQuery();


//functions of Query   
void MainClass::MyQuery::LaunchQuery() const
{
    this->start();
}

void MainClass::Query::run()
{
    const MainClass& mainClass = MainClass::GetInstance();
    const jclass& obj = mainClass.GetClass();
    JNIEnv& env = mainClass.GetJavaEnvironment();
    jmethodID methodId = env.GetMethodID(obj, "SearchQuery", "(Ljava/lang/String;)V"); //Run-time error

    if(methodId != 0)
    {
        //calling "SearchQuery" function
    }

Now, if run this code in a single thread - everything is fine, but if try to run above code - using multithreading, it causes run-time error by message "Unhandled exception at 0x777715de in MyApp.exe: 0xC0000005: Access violation reading location 0x000000ac." when I try to get method id. I've tried also with boost::thread but result was the same.

So why it fails when I'm doing it in a separate thread, when in the same thread everything is fine? Any ideas?

c++
multithreading
qt
java-native-interface
runtime-error
asked on Stack Overflow Aug 5, 2013 by nabroyan

1 Answer

12

Scroll down to 'Attaching to the VM' in the JNI docs :

http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/invocation.html

The JNI interface pointer (JNIEnv) is valid only in the current thread. Should another thread need to access the Java VM, it must first call AttachCurrentThread() to attach itself to the VM and obtain a JNI interface pointer.

answered on Stack Overflow Aug 5, 2013 by Graham Griffiths • edited Jun 23, 2016 by NuSkooler

User contributions licensed under CC BY-SA 3.0