Skip to main content

How to Develop Java Library

Introduction

GraphAr Java library based on GraphAr C++ library and an efficient FFI for Java and C++ called FastFFI.

Source Code Level

  • Interface
  • Class
  • JNI code
  • GraphAr C++ library

If you want to use classes or functions of GraphAr C++ library through JAVA SDK, you only need to write interfaces with annotations. After the interfaces are ready, the java code for the interfaces and the the C++ code which include JNI code for native methods will be automatically generated by FastFFI.For annotation’s usage, please refer to FastFFI.

Runtime Level

Interfaces and classes will be compiled to bytecode. Usually, JNI code will be compiled to bitcode as a part of dynamic library which can be called by native methods directly. If llvm4jni is enable, suitable method in JNI will be transferred to bytecode.

For decoupling the implementation of C++ and Java, we use a bridge dynamic library called gar-jni to connect them, it will integrate all C++ dependencies(e.g. JNI code, GraphAr C++ library and arrow C++) and can be called by native methods in Java directly. Most JNI code is generated by FastFFI, but some JNI code is written by ourselves, such as JNI code for transferring VectorSchemaRoot into arrow::Table.

To build the bridge dynamic library, here is main part of our CMakeLists.txt:

# set auto-generated JNI code and handwriting JNI code as source files
file(GLOB SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/target/generated-sources/annotations/*.cc" "${CMAKE_CURRENT_SOURCE_DIR}/target/generated-test-sources/test-annotations/*.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/src/main/cpp/ffi/*.cc")
# remove auto-generated JNI code for specific method cause we have handwriting JNI code for it
list(REMOVE_ITEM SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/target/generated-sources/annotations/jni_com_alibaba_graphar_arrow_ArrowTable_Static_cxx_0x58c7409.cc")

set(LIBNAME "gar-jni")

# find JNI related libraries
find_package(JNI REQUIRED)
include_directories(SYSTEM ${JAVA_INCLUDE_PATH})
include_directories(SYSTEM ${JAVA_INCLUDE_PATH2})

# some JNI code depends on arrow
find_package(Arrow REQUIRED)
# build graphar-cpp in specific version
include(graphar-cpp)
build_graphar_cpp()

# build the bridge JNI library
add_library(${LIBNAME} SHARED ${SOURCES})
# include graphar-cpp headers
target_include_directories(${LIBNAME} SYSTEM BEFORE PRIVATE ${GRAPHAR_INCLUDE_DIR})
# link graphar-cpp and arrow
target_link_libraries(${LIBNAME} ${CMAKE_JNI_LINKER_FLAGS} gar_shared)
target_link_libraries(${LIBNAME} ${CMAKE_JNI_LINKER_FLAGS} Arrow::arrow_static)

More about usage of CMake, please refer to CMake's official website.

Building GraphAr Java

Please refer to GraphAr Java Library user guide.

How To Test

export GAR_TEST_DATA=$PWD/../../testing/
mvn clean test

This will build GraphAr C++ library internally for Java. If you already installed GraphAr C++ library in your system, you can append this option to skip: -DbuildGarCPP=OFF.

Code Style

We follow AOSP Java code style. To ensure CI for checking code style will pass, please ensure check below is success:

mvn spotless:check

If there are violations, running command below to automatically format:

mvn spotless:apply