119 cedaPrepareUseJni

Linux

On Ubuntu Linux 18.04 calling find_package(Java REQUIRED) gives:

    -- Found Java: /usr/bin/java (found version "11.0.7")
    Java_JAVA_EXECUTABLE = /usr/bin/java
    Java_JAVAC_EXECUTABLE = /usr/bin/javac
    Java_JAVAH_EXECUTABLE = Java_JAVAH_EXECUTABLE-NOTFOUND
    Java_JAVADOC_EXECUTABLE = /usr/bin/javadoc
    Java_VERSION_STRING = 11.0.7
    Java_VERSION = 11.0.7

Android

On both Windows and Linxus we simply assume the Android NDK already has a jni.h available, so no need to call the problematic find_package(JNI REQUIRED) in order to initialise JNI_INCLUDE_DIRS

Windows

Under Windows, when using the Android NDK an error can result when trying to find package JNI because some parts are missing. See https://stackoverflow.com/questions/51047978/cmake-could-not-find-jni/51764145

The error message is:

    Could NOT find JNI (missing: JAVA_AWT_LIBRARY JAVA_JVM_LIBRARY JAVA_INCLUDE_PATH2 JAVA_AWT_INCLUDE_PATH)

See documentation of FindJNI (https://cmake.org/cmake/help/latest/module/FindJNI.html) 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.

This workaround used to work but no longer works?

Still getting error:

     Could NOT find JNI (missing: JAVA_AWT_LIBRARY JAVA_JVM_LIBRARY JAVA_INCLUDE_PATH2 JAVA_AWT_INCLUDE_PATH)

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)

Linux

The Android NDK has jni.h in the paths

      ndk-bundle/sysroot/usr/include/jni.h
      ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/jni.h

At least one of these paths is already available (through --sysroot compiler option?)

Therefore jni.h is already available, so no need to call


    find_package(JNI REQUIRED)

in order to initialise JNI_INCLUDE_DIRS.

This is perhaps just as well because find_package(JNI REQUIRED) finds paths under /usr/lib/jvm which isn't what we want.

cedaPrepareUseJni


macro(cedaPrepareUseJni)
    message("JAVA_HOME = $ENV{JAVA_HOME}")

    find_package(Java REQUIRED)
    message("Java_JAVA_EXECUTABLE = ${Java_JAVA_EXECUTABLE}")
    message("Java_JAVAC_EXECUTABLE = ${Java_JAVAC_EXECUTABLE}")
    message("Java_JAVAH_EXECUTABLE = ${Java_JAVAH_EXECUTABLE}")
    message("Java_JAVADOC_EXECUTABLE = ${Java_JAVADOC_EXECUTABLE}")
    message("Java_VERSION_STRING = ${Java_VERSION_STRING}")
    message("Java_VERSION = ${Java_VERSION}")

    if (${CMAKE_SYSTEM_NAME} STREQUAL "Android")
        set(JNI_INCLUDE_DIRS "")
    else()
        # On Linux we get:
        #   -- Found JNI: /usr/lib/jvm/default-java/lib/libjawt.so
        #   JNI_INCLUDE_DIRS = /usr/lib/jvm/default-java/include;/usr/lib/jvm/default-java/include/linux;/usr/lib/jvm/default-java/include
        #   JNI_LIBRARIES = /usr/lib/jvm/default-java/lib/libjawt.so;/usr/lib/jvm/default-java/lib/server/libjvm.so
        find_package(JNI REQUIRED)
    endif()

    message ("JNI_INCLUDE_DIRS = ${JNI_INCLUDE_DIRS}")
    message ("JNI_LIBRARIES = ${JNI_LIBRARIES}")        # Not used, don't care what JNI_LIBRARIES equals
endmacro()