libJTool is a small C++20 facade for safer and less repetitive JNI integration.
The API is centered on the move-only jtool::JHelper context. Operations that need JVM state are regular helper member functions, while jtool::JTool only owns process-wide JVM initialization. Public headers do not include or require jni.h.
- Thread-aware
JNIEnvresolution from a storedJavaVM. - Static and instance method invocation.
- Static and instance field access.
- RAII local/global reference ownership with move-only and shared handles.
- Java exception inspection and creation.
- Primitive boxing, strings, and byte arrays.
- Fluent and one-shot JNI method-signature construction.
- A single umbrella include with class-specific headers underneath.
- CMake 3.24+
- A C++20 compiler
- JDK 11 or newer, discoverable by CMake
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --config ReleaseTests and examples are optional:
cmake -S . -B build -DJTOOL_BUILD_TESTS=ON -DJTOOL_BUILD_EXAMPLES=ON
cmake --build build --config Release
ctest --test-dir build --build-config Release --output-on-failureWindows users should use the Visual Studio generator described in Testing, or run python scripts/Build.py --run-tests --fresh.
Include JNI only in your implementation file, then include libJTool:
#include <jni.h>
#include <libJTool/JTool.hpp>
extern "C" JNIEXPORT jint JNICALL
Java_com_example_NativeApi_parseNumber(JNIEnv* env, jclass, jstring text) {
auto helper = jtool::JHelper::fromJniEnv(env);
auto integerClass = helper.findClass("java/lang/Integer");
auto method = helper.createMethod(
integerClass,
jtool::JavaType::kInt,
"parseInt",
jtool::JSignature::method({jtool::kStringSignature}, jtool::kIntSignature).c_str(),
{jtool::JniObject::objectValue(text, jtool::JavaType::kStringObject)});
jint result = 0;
if (helper.invoke(method)) {
result = helper.getReturnValue(method)->m_value.m_int;
}
return result;
}The method and class handles release their JNI global references automatically when the callback returns.