nalgenes
nalgenes

Reputation: 370

CMake could not find JNI

I created a new Android Studio Project with C++ support and did not add anything to it. The project builds, compiles and runs with CMake. I then added the following two lines of code to CMakeLists.txt at the bottom of the file and I get a CMake build error.

find_package(Java COMPONENTS Development)       # Line 47
find_package(JNI REQUIRED)                      # Line 48

And this is the error I get when building the project

-- Found Java: /usr/lib/jvm/java-10-oracle/bin/java (found version "10.0.1") found components:  Development 
-- Configuring incomplete, errors occurred!
CMake Error at /home/xxxxx/Android/Sdk/cmake/3.6.4111459/share/cmake-3.6/Modules/FindPackageHandleStandardArgs.cmake:148 (message):
  Could NOT find JNI (missing: JAVA_AWT_LIBRARY JAVA_JVM_LIBRARY
  JAVA_INCLUDE_PATH2 JAVA_AWT_INCLUDE_PATH)
Call Stack (most recent call first):
  /home/xxxxxx/Android/Sdk/cmake/3.6.4111459/share/cmake-3.6/Modules/FindPackageHandleStandardArgs.cmake:388 (_FPHSA_FAILURE_MESSAGE)
  /home/xxxxxx/Android/Sdk/cmake/3.6.4111459/share/cmake-3.6/Modules/FindJNI.cmake:314 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
  CMakeLists.txt:48 (find_package)
See also "/home/xxxxx/AndroidStudioProjects/MyApplication/app/.externalNativeBuild/cmake/release/x86_64/CMakeFiles/CMakeOutput.log".
External native generate JSON release: JSON generation completed with problems

CMake runs when being called form the command line, but fails inside Android Studio for some reason and I am not sure why.

This is all that is in CMakeLists.txt file. It compiles in cmd with the command cmake.

cmake_minimum_required(VERSION 3.4.1)

find_package(Java COMPONENTS Development)
find_package(JNI REQUIRED)

This is the cmd output

E:\Users\xxxxx\AndroidStudioProjects\MyApplication\app\build>cmake ..
-- Configuring done
-- Generating done
-- Build files have been written to: E:/Users/xxxxx/AndroidStudioProjects/MyApplication/app/build

When I try to add it compile it in Android Studio using gradle I get the following error on Windows 10 pro 64 bit

Microsoft Windows [Version 10.0.17134.112]
(c) 2018 Microsoft Corporation. All rights reserved.

E:\Users\xxxxx\AndroidStudioProjects\MyApplication>gradlew build --stacktrace

> Task :app:generateJsonModelDebug 
External native generate JSON debug: starting JSON generation
External native generate JSON debug: using platform version 24 for ABI ARMEABI_V7A and min SDK version 24
External native generate JSON debug: noticing that build file 'E:\Users\xxxxx\AndroidStudioProjects\MyApplication\app\CMakeLists.txt' is out of date with respect to E:\Users\xxxxx\AndroidStudioProjects\MyApplication\app\.extern
alNativeBuild\cmake\debug\armeabi-v7a\android_gradle_build.json
External native generate JSON debug: rebuilding JSON E:\Users\xxxxx\AndroidStudioProjects\MyApplication\app\.externalNativeBuild\cmake\debug\armeabi-v7a\android_gradle_build.json due to:
External native generate JSON debug: - a dependent build file changed
External native generate JSON debug: keeping json folder 'E:\Users\xxxxx\AndroidStudioProjects\MyApplication\app\.externalNativeBuild\cmake\debug\armeabi-v7a' but regenerating project
External native generate JSON debug: executing cmake Executable : E:\Android\SDK\cmake\3.6.4111459\bin\cmake.exe
arguments :
-HE:\Users\xxxxx\AndroidStudioProjects\MyApplication\app
-BE:\Users\xxxxx\AndroidStudioProjects\MyApplication\app\.externalNativeBuild\cmake\debug\armeabi-v7a
-DANDROID_ABI=armeabi-v7a
-DANDROID_PLATFORM=android-24
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=E:\Users\xxxxx\AndroidStudioProjects\MyApplication\app\build\intermediates\cmake\debug\obj\armeabi-v7a
-DCMAKE_BUILD_TYPE=Debug
-DANDROID_NDK=E:\Android\SDK\ndk-bundle
-DCMAKE_CXX_FLAGS=
-DCMAKE_TOOLCHAIN_FILE=E:\Android\SDK\ndk-bundle\build\cmake\android.toolchain.cmake
-DCMAKE_MAKE_PROGRAM=E:\Android\SDK\cmake\3.6.4111459\bin\ninja.exe
-GAndroid Gradle - Ninja
jvmArgs :


CMake Error at E:/Android/SDK/cmake/3.6.4111459/share/cmake-3.6/Modules/FindPackageHandleStandardArgs.cmake:148 (message):
  Could NOT find JNI (missing: JAVA_AWT_LIBRARY JAVA_JVM_LIBRARY
  JAVA_INCLUDE_PATH2 JAVA_AWT_INCLUDE_PATH)
Call Stack (most recent call first):
  E:/Android/SDK/cmake/3.6.4111459/share/cmake-3.6/Modules/FindPackageHandleStandardArgs.cmake:388 (_FPHSA_FAILURE_MESSAGE)
  E:/Android/SDK/cmake/3.6.4111459/share/cmake-3.6/Modules/FindJNI.cmake:314 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
  CMakeLists.txt:4 (find_package)
-- Configuring incomplete, errors occurred!
See also "E:/Users/xxxxx/AndroidStudioProjects/MyApplication/app/.externalNativeBuild/cmake/debug/armeabi-v7a/CMakeFiles/CMakeOutput.log".

Upvotes: 25

Views: 38937

Answers (7)

Hyeonseo Yang
Hyeonseo Yang

Reputation: 1128

For MacOS users using openjdk, with jenv, you should

jenv add /opt/homebrew/Cellar/openjdk@17/17.0.9/libexec/openjdk.jdk/Contents/Home

not

jenv add /opt/homebrew/Cellar/openjdk@17/17.0.9/

Only.

Upvotes: 1

vinay perumalla
vinay perumalla

Reputation: 1

CMake Error at /usr/share/cmake-3.22/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
  Could NOT find JNI (missing: JAVA_AWT_LIBRARY JAVA_JVM_LIBRARY
  JAVA_INCLUDE_PATH2 JAVA_AWT_INCLUDE_PATH)
Call Stack (most recent call first):
  /usr/share/cmake-3.22/Modules/FindPackageHandleStandardArgs.cmake:594 (_FPHSA_FAILURE_MESSAGE)
  /usr/share/cmake-3.22/Modules/FindJNI.cmake:382 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
  CMakeLists.txt:19 (find_package)

Update the cmake if you are trying in virtualenv check have you installed cmake or not. Install cmake version cmake-3.26.4-h96355d8_0

conda install cmake

Upvotes: 0

UdaraWanasinghe
UdaraWanasinghe

Reputation: 2852

The FindJNI module in CMake determines if Java is installed and where the include files and libraries are. Some features like AWT are not in the Jvm bundled with the Android. The solution is to remove the REQUIRED argument and check if your variable is set.

find_package(JNI)
if (NOT JAVA_INCLUDE_PATH)
    message(FATAL_ERROR "Failed to find Java include path.")
endif()

Starting with CMake 3.24 this is no longer an issue. The latest CMake version detects if the platform is Android and marks components not in Android as not required. So that you can use find_library(JNI REQUIRED) as usual, consider updating the CMake version to the latest to avoid this issue.

Upvotes: 0

Bensuperpc
Bensuperpc

Reputation: 1405

I found a solution that works for me:

cmake_minimum_required(VERSION 3.10)
project("ktaglib")

set(JAVA_AWT_LIBRARY "$ENV{JAVA_HOME}/lib/libjawt.so")
set(JAVA_JVM_LIBRARY "$ENV{JAVA_HOME}/lib/server/libjvm.so")

set(JAVA_INCLUDE_PATH "$ENV{JAVA_HOME}/include")
set(JAVA_INCLUDE_PATH2 "$ENV{JAVA_HOME}/include/linux")
set(JAVA_AWT_INCLUDE_PATH "$ENV{JAVA_HOME}/include")

find_package(JNI REQUIRED)

You must set the environment variable JAVA_HOME="/usr/lib/jvm/java-11-openjdk-amd64" beforehand.

More info: https://github.com/dockcross/dockcross/issues/576

Upvotes: 9

Mizux
Mizux

Reputation: 9301

Same on alpine:edge docker image, fixed using:

ENV JAVA_HOME=/usr/lib/jvm/java-1.8-openjdk
RUN apk add --no-cache openjdk8

ref: https://pkgs.alpinelinux.org/contents?branch=edge&name=openjdk8&arch=x86_64&repo=community

Upvotes: 0

angelo.mastro
angelo.mastro

Reputation: 1784

Could NOT find JNI (missing: JAVA_AWT_LIBRARY JAVA_JVM_LIBRARY

Solved with

sudo apt-get install -y openjdk-8-jdk
sudo apt-get install -y default-jdk
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64

Upvotes: 36

psyill
psyill

Reputation: 911

As the CMake version bundled with Android tries to tell you, it can't find the JNI package because some parts were missing:

missing: JAVA_AWT_LIBRARY JAVA_JVM_LIBRARY JAVA_INCLUDE_PATH2 JAVA_AWT_INCLUDE_PATH

Checking the documentation for FindJNI (https://cmake.org/cmake/help/latest/module/FindJNI.html) these variables are set to the locations of libraries and headers not shipped with the Android version of JNI (to little surprise, Android does not included the AWT library for instance). When running find_package(JNI REQUIRED), the FindJNI code checks if these variables are set and if not, issues an error.

A workaround is to set these variables yourself, before calling find_package:

# We are only interested in finding jni.h: we do not care about extended JVM
# functionality or the AWT library.
set(JAVA_AWT_LIBRARY NotNeeded)
set(JAVA_JVM_LIBRARY NotNeeded)
set(JAVA_INCLUDE_PATH2 NotNeeded)
set(JAVA_AWT_INCLUDE_PATH NotNeeded)
find_package(JNI REQUIRED)

Be aware though, that your code will only be able to use jni.h and its functionality: if it tries to access any other part of the JNI package it will fail (probably at compile time) because essentially, you have tricked CMake into thinking that the entire package was found, when in reality only a part of it exists in the Android setup.

Upvotes: 28

Related Questions