A header-only C++ library that makes working with the Java Native Interface (JNI) safer and more convenient.
Working with JNI directly can be error-prone and verbose. This library wraps the raw JNI calls with modern C++ abstractions to provide:
- Exception safety with automatic error checking
- RAII-based resource management
- Simplified string conversion
- Cleaner syntax for common JNI operations
- Exception Handling: Automatic JNI exception checking and propagation to C++ exceptions
- Safe Resource Management: RAII wrapper for JNI references to prevent leaks (
ScopedLocalRef
) - Type-Safe Calls: Template-based method calls with proper type handling
- String Conversion: Easy conversion between Java and C++ strings
- Simplified API: Readable wrapper functions for common JNI operations
- Support for All Basic Types: Complete implementations for all Java primitive types and object references
This is a header-only library. Simply include the header in your Android NDK project:
#include "JniHelper.hpp"
Make sure to place the header file in your project's include path.
// Call a Java method from C++
jstring result = jni::CallMethod<jstring>(env, javaObj, "getMessage", "()Ljava/lang/String;");
std::string cppString = jni::JStringToString(env, result);
// Call a static Java method
jint value = jni::CallStaticMethod<jint>(env, "com/example/Utils", "calculateValue", "(I)I", 42);
// Create a new Java object
jobject newObj = jni::NewObject(env, "java/lang/StringBuilder", "()V");
jni::CallMethod<void>(env, newObj, "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", "Hello, JNI!");
jstring result = jni::CallMethod<jstring>(env, newObj, "toString", "()Ljava/lang/String;");
// Get field values
jint count = jni::GetField<jint>(env, javaObj, "count");
jstring name = jni::GetField<jstring>(env, javaObj, "name", "Ljava/lang/String;");
// Get static field value
jlong timeout = jni::GetStaticField<jlong>(env, "com/example/Config", "TIMEOUT_MS");
// Automatically manage JNI local references
{
jclass cls = env->FindClass("java/lang/String");
jni::ScopedLocalRef<jclass> safeClass(env, cls); // Will be released automatically
// Use safeClass.get() to access the reference
jmethodID mid = env->GetMethodID(safeClass.get(), "length", "()I");
}
// No need to call DeleteLocalRef, it's handled by ScopedLocalRef's destructor
try {
// This will automatically check for JNI exceptions
jni::CallMethod<void>(env, javaObj, "methodThatMightThrow", "()V");
} catch (const jni::JNIException& e) {
std::cerr << "Java exception occurred: " << e.what() << std::endl;
}
JNIException
: Custom exception class for JNI errorsJNI_CHECK_EXCEPTION
: Macro to check and throw JNI exceptions
ScopedLocalRef<T>
: RAII wrapper for JNI local references
JStringToString(JNIEnv*, jstring)
: Convert a Java string to C++ stringStringToJString(JNIEnv*, const std::string&)
: Convert a C++ string to Java string
FindClass(JNIEnv*, const char*)
: Find a Java class with exception checkingGetMethodID(JNIEnv*, jclass, const char*, const char*)
: Get a method ID with exception checkingGetStaticMethodID(JNIEnv*, jclass, const char*, const char*)
: Get a static method ID with exception checking
GetFieldID(JNIEnv*, jclass, const char*, const char*)
: Get a field ID with exception checkingGetStaticFieldID(JNIEnv*, jclass, const char*, const char*)
: Get a static field ID with exception checkingGetField<T>(JNIEnv*, jobject, const char*, const char*)
: Get field value with type safetyGetStaticField<T>(JNIEnv*, const char*, const char*, const char*)
: Get static field value with type safety
CallMethod<ReturnType, Args...>(JNIEnv*, jobject, const char*, const char*, Args...)
: Call instance methodsCallStaticMethod<ReturnType, Args...>(JNIEnv*, const char*, const char*, const char*, Args...)
: Call static methodsNewObject<Args...>(JNIEnv*, const char*, const char*, Args...)
: Create new Java objects
Contributions are welcome! Please feel free to submit a Pull Request.
For any questions, collaboration requests, or updates, feel free to reach out via:
Telegram Channel: Join Channel
Telegram Contact: Contact Me
Website: My Website
Email: [email protected]
If you'd like to, you can support me on my Website
- 1.0.0 (2025-03-19): Initial release
MIT License