blob: b310c0507182a12c96c4fc93b4c422222aaa8ee1 [file] [view]
---
id: how_to_develop_java_ffi
title: How to Develop Java FFI Library
sidebar_position: 2
---
## Introduction
GraphAr Java library based on GraphAr C++ library and an efficient FFI
for Java and C++ called
[FastFFI](https://github.com/alibaba/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 annotations usage, please refer to
[FastFFI](https://github.com/alibaba/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.gJNI 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:
```cmake
# 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](https://cmake.org/).
## Building GraphAr Java
Please refer to
[GraphAr Java Library user guide](getting-started).
## How To Test
```bash
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](https://source.android.com/docs/setup/contribute/code-style).
To ensure CI for checking code style will pass, please ensure check
below is success:
```bash
mvn spotless:check
```
If there are violations, running command below to automatically format:
```bash
mvn spotless:apply
```