title: Android Studio: Bad JNI version passed in linked C++ library
body: <p>I am trying to use a C++ library with Java bindings inside an Android Studio project. I have linked the CMakeLists.txt as an external C++ Project and it builds with zero errors and the libraries appear under the cpp folder inside my application. The library is located in <code>/MyApplication/app/dnp3/</code><a href="https://i.stack.imgur.com/ilw3H.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ilw3H.png" alt="enter image description here"></a> </p>
  
  <p>When I try to run it on a Galaxy S7 by calling the library using <code>static{System.loadLibrary("opendnp3java")}</code> inside a JAVA file, I get the following error related to JNI. I can load any of the other libraries without getting a crash</p>
  
  <pre><code>07-10 13:02:54.019 2738-2738/com.company.MyApplication E/art: Bad JNI version passed to GetEnv: 65544
  
      --------- beginning of crash
  07-10 13:02:54.020 2738-2738/com.company.MyApplication A/libc: /home/xxxxxx/AndroidStudioProjects/MyApplication/app/dnp3/java/cpp/adapters/JNI.cpp:43: static JNIEnv *JNI::GetEnv(): assertion "env" failed
      Fatal signal 6 (SIGABRT), code -6 in tid 2738 (rols.MyApplication)
  </code></pre>
  
  <p>This is the function inside JNI.cpp that causes the crash</p>
  
  <pre><code>JNIEnv* JNI::GetEnv()
  {
      JNIEnv* env = nullptr;
      vm-&gt;GetEnv((void**)&amp;env, OPENDNP3_JNI_VERSION);
      assert(env);         // This line casues the error
      return env;
  }
  </code></pre>
  
  <p><code>OPENDNP3_JNI_VERSION</code> is defined in JNI.h as the following</p>
  
  <pre><code>#define OPENDNP3_JNI_VERSION JNI_VERSION_1_8
  </code></pre>
  
  <p>This is my <code>build.gradle</code> file. I had to hardcode the JAVA paths as Android Studio CMake cannot find JNI without it and throws an error caused by not finding JNI. (CMake outside of Android Studio has no problem finding JNI)</p>
  
  <pre><code>apply plugin: 'com.android.application'
  
  android {
      compileSdkVersion 28
      defaultConfig {
          publishNonDefault true
          applicationId "com.comapny.MyApplication"
          minSdkVersion 24
          targetSdkVersion 28
          versionCode 1
          versionName "1.0"
          testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
  
          externalNativeBuild {
              cmake {
                  arguments "-DANDROID_ABI=arm64-v8a",
                          "-DJAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-amd64",
                          //"-DJAVA_DIR=/usr/lib/jvm/java-1.8.0-openjdk-amd64/bin/",
                          "-DJAVA_AWT_LIBRARY=/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/amd64/libjawt.so",
                          "-DJAVA_JVM_LIBRARY=/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/amd64/server/libjvm.so",
                          //"-DJAVA_INCLUDE_PATH=JAVA_INCLUDE_PATH=/usr/lib/jvm/java-1.8.0-openjdk-amd64/include",
                          "-DJAVA_INCLUDE_PATH2=/usr/lib/jvm/java-1.8.0-openjdk-amd64/include/linux",
                          "-DJAVA_AWT_INCLUDE_PATH=/usr/lib/jvm/java-1.8.0-openjdk-amd64/include",
                          "-DDNP3_JAVA=ON"
              }
          }
          ndk {
              abiFilters 'arm64-v8a'
          }
      }
      buildTypes {
          release {
              minifyEnabled false
              proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
          }
      }
      externalNativeBuild {
          cmake {
              path 'dnp3/CMakeLists.txt'
          }
      }
      buildToolsVersion '28.0.0'
  }
  
  dependencies {
      implementation fileTree(dir: 'libs', include: ['*.jar'])
      implementation 'com.android.support:appcompat-v7:28.0.0-alpha3'
      implementation 'com.android.support.constraint:constraint-layout:1.1.2'
      testImplementation 'junit:junit:4.12'
      androidTestImplementation 'com.android.support.test:runner:1.0.2'
      androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
  }
  </code></pre>
  
  <p>CMake has the following output when building the project </p>
  
  <pre><code>External native generate JSON release: building json with force flag false
  External native generate JSON release: starting JSON generation
  External native generate JSON release: using platform version 24 for ABI ARM64_V8A and min SDK version 24
  External native generate JSON release: rebuilding JSON /home/xxxxxx/AndroidStudioProjects/MyApplication/app/.externalNativeBuild/cmake/release/arm64-v8a/android_gradle_build.json due to:
  External native generate JSON release: - expected json /home/xxxxxx/AndroidStudioProjects/MyApplication/app/.externalNativeBuild/cmake/release/arm64-v8a/android_gradle_build.json file is not present, will remove stale json folder
  External native generate JSON release: - missing previous command file /home/xxxxxx/AndroidStudioProjects/MyApplication/app/.externalNativeBuild/cmake/release/arm64-v8a/cmake_build_command.txt, will remove stale json folder
  External native generate JSON release: removing stale contents from '/home/xxxxxx/AndroidStudioProjects/MyApplication/app/.externalNativeBuild/cmake/release/arm64-v8a'
  External native generate JSON release: created folder '/home/xxxxxx/AndroidStudioProjects/MyApplication/app/.externalNativeBuild/cmake/release/arm64-v8a'
  External native generate JSON release: executing cmake Executable : /home/xxxxxx/Android/Sdk/cmake/3.6.4111459/bin/cmake
  arguments : 
  -H/home/xxxxxx/AndroidStudioProjects/MyApplication/app/dnp3
  -B/home/xxxxxx/AndroidStudioProjects/MyApplication/app/.externalNativeBuild/cmake/release/arm64-v8a
  -DANDROID_ABI=arm64-v8a
  -DANDROID_PLATFORM=android-24
  -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=/home/xxxxxx/AndroidStudioProjects/MyApplication/app/build/intermediates/cmake/release/obj/arm64-v8a
  -DCMAKE_BUILD_TYPE=Release
  -DANDROID_NDK=/home/xxxxxx/Android/Sdk/ndk-bundle
  -DCMAKE_TOOLCHAIN_FILE=/home/xxxxxx/Android/Sdk/ndk-bundle/build/cmake/android.toolchain.cmake
  -DCMAKE_MAKE_PROGRAM=/home/xxxxxx/Android/Sdk/cmake/3.6.4111459/bin/ninja
  -GAndroid Gradle - Ninja
  -DANDROID_ABI=arm64-v8a
  -DJAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-amd64
  -DJAVA_AWT_LIBRARY=/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/amd64/libjawt.so
  -DJAVA_JVM_LIBRARY=/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/amd64/server/libjvm.so
  -DJAVA_INCLUDE_PATH2=/usr/lib/jvm/java-1.8.0-openjdk-amd64/include/linux
  -DJAVA_AWT_INCLUDE_PATH=/usr/lib/jvm/java-1.8.0-openjdk-amd64/include
  -DDNP3_JAVA=ON
  jvmArgs : 
  
  
  -- Check for working C compiler: /home/xxxxxx/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin/clang
  -- Check for working C compiler: /home/xxxxxx/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin/clang -- works
  -- Detecting C compiler ABI info
  -- Detecting C compiler ABI info - done
  -- Detecting C compile features
  -- Detecting C compile features - done
  -- Check for working CXX compiler: /home/xxxxxx/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++
  -- Check for working CXX compiler: /home/xxxxxx/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ -- works
  -- Detecting CXX compiler ABI info
  -- Detecting CXX compiler ABI info - done
  -- Detecting CXX compile features
  -- Detecting CXX compile features - done
  CMake build is: Release
  -- Looking for pthread.h
  -- Looking for pthread.h - found
  -- Looking for pthread_create
  -- Looking for pthread_create - found
  -- Found Threads: TRUE  
  -- Found Java: /usr/lib/jvm/java-1.8.0-openjdk-amd64/bin/java (found version "1.8.0.171") found components:  Development 
  -- Found JNI: /usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/amd64/libjawt.so  
  ASIO has been checked out as a git submodule: /home/xxxxxx/AndroidStudioProjects/MyApplication/app/dnp3/deps/asio/asio/include
  -- Configuring done
  -- Generating done
  -- Build files have been written to: /home/xxxxxx/AndroidStudioProjects/MyApplication/app/.externalNativeBuild/cmake/release/arm64-v8a
  External native generate JSON release: done executing cmake
  External native generate JSON release: write build output /home/xxxxxx/AndroidStudioProjects/MyApplication/app/.externalNativeBuild/cmake/release/arm64-v8a/cmake_build_output.txt
  External native generate JSON release: write command file /home/xxxxxx/AndroidStudioProjects/MyApplication/app/.externalNativeBuild/cmake/release/arm64-v8a/cmake_build_command.txt
  External native generate JSON release: JSON generation completed without problems
  
  CONFIGURE SUCCESSFUL in 9s
  External native generate JSON debug: streaming 1 JSON files
  External native generate JSON debug: string JSON file /home/xxxxxx/AndroidStudioProjects/MyApplication/app/.externalNativeBuild/cmake/debug/arm64-v8a/android_gradle_build.json
  External native generate JSON release: streaming 1 JSON files
  External native generate JSON release: string JSON file /home/xxxxxx/AndroidStudioProjects/MyApplication/app/.externalNativeBuild/cmake/release/arm64-v8a/android_gradle_build.json
  </code></pre>
  
  <p>AS you can see from this output, CMake is able to find JNI under <code>/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/amd64/libjawt.so</code>, so I am not sure why I get an error related to passing a bad JNI version. The bindings also require Java 1.8 or greater</p>
  
  <p>I am running on virtual Ubuntu machine</p>
  
  <pre><code>Distributor ID: Ubuntu
  Description:    Ubuntu 18.04 LTS
  Release:    18.04
  Codename:   bionic
  </code></pre>
  
  <p>Any help or ideas is appreciated.</p>
  
  <p>Thank you!</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>The Java library bindings of the C++ project is Maven based and requires the following inside the projects pom.xml  file. So, I put it inside the dependencies of the build.gradle.</p>
  
  <pre><code>&lt;dependency&gt;
      &lt;groupId&gt;com.automatak.dnp3&lt;/groupId&gt;
      &lt;artifactId&gt;opendnp3-bindings&lt;/artifactId&gt;
      &lt;version&gt;${opendnp3.version}&lt;/version&gt;
  &lt;/dependency&gt;
  
  
  dependencies {
      . . .
      compile "com.automatak.dnp3:opendnp3-bindings:${opendnp3.version}"
  }
  </code></pre>
  
  <p>But this throws the following error</p>
  
  <pre><code>Could not get unknown property 'opendnp3' for object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler
  </code></pre>
  
  <p><strong>EDIT 2</strong></p>
  
  <p>I redefined OPENDNP3_JNI_VERSION</p>
  
  <pre><code>#define OPENDNP3_JNI_VERSION JNI_VERSION_1_6
  </code></pre>
  
  <p>And it throws <a href="https://www.pastebucket.com/566760" rel="nofollow noreferrer">this error</a> when trying to run on the project</p>