2
0

JNI reference memory management.

This commit is contained in:
Maarten Billemont 2019-09-24 21:26:07 -04:00
parent 1c6a5256c1
commit bf5e30c2c7

View File

@ -9,35 +9,39 @@
static jobject logger; static jobject logger;
static JNIEnv *env; static JNIEnv *env;
static int counter;
void mpw_log_app(LogLevel level, const char *format, ...) { void mpw_log_app(LogLevel level, const char *format, ...) {
jmethodID method = NULL;
jclass class = (*env)->GetObjectClass( env, logger );
if (level >= LogLevelTrace)
method = (*env)->GetMethodID( env, class, "trace", "(Ljava/lang/String;)V" );
else if (level == LogLevelDebug)
method = (*env)->GetMethodID( env, class, "debug", "(Ljava/lang/String;)V" );
else if (level == LogLevelInfo)
method = (*env)->GetMethodID( env, class, "info", "(Ljava/lang/String;)V" );
else if (level == LogLevelWarning)
method = (*env)->GetMethodID( env, class, "warn", "(Ljava/lang/String;)V" );
else if (level <= LogLevelError)
method = (*env)->GetMethodID( env, class, "error", "(Ljava/lang/String;)V" );
va_list args; va_list args;
va_start( args, format ); va_start( args, format );
if (class && method && logger) { if (logger && (*env)->PushLocalFrame( env, 16 ) == OK) {
jmethodID method = NULL;
jclass class = (*env)->GetObjectClass( env, logger );
if (level >= LogLevelTrace)
method = (*env)->GetMethodID( env, class, "trace", "(Ljava/lang/String;)V" );
else if (level == LogLevelDebug)
method = (*env)->GetMethodID( env, class, "debug", "(Ljava/lang/String;)V" );
else if (level == LogLevelInfo)
method = (*env)->GetMethodID( env, class, "info", "(Ljava/lang/String;)V" );
else if (level == LogLevelWarning)
method = (*env)->GetMethodID( env, class, "warn", "(Ljava/lang/String;)V" );
else if (level <= LogLevelError)
method = (*env)->GetMethodID( env, class, "error", "(Ljava/lang/String;)V" );
char *message = NULL; char *message = NULL;
int length = vasprintf(&message, format, args); int length = vasprintf( &message, format, args );
if (length > 0) if (message) {
(*env)->CallVoidMethod(env, logger, method, (*env)->NewStringUTF( env, message )); (*env)->CallVoidMethod( env, logger, method, (*env)->NewStringUTF( env, message ) );
if (message) mpw_free( &message, (size_t)max( 0, length ) );
mpw_free(&message, (size_t) length); }
(*env)->PopLocalFrame( env, NULL );
return;
} }
else
// Can't log via slf4j, fall back to cli logger. // Can't log via slf4j, fall back to cli logger.
mpw_vlog_cli( level, format, args ); mpw_vlog_cli( level, format, args );
va_end( args ); va_end( args );
} }
@ -50,7 +54,7 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
jmethodID method = (*env)->GetStaticMethodID( env, class, "getLogger", "(Ljava/lang/String;)Lorg/slf4j/Logger;" ); jmethodID method = (*env)->GetStaticMethodID( env, class, "getLogger", "(Ljava/lang/String;)Lorg/slf4j/Logger;" );
jstring name = (*env)->NewStringUTF( env, "com.lyndir.masterpassword.algorithm" ); jstring name = (*env)->NewStringUTF( env, "com.lyndir.masterpassword.algorithm" );
if (class && method && name) if (class && method && name)
logger = (*env)->CallStaticObjectMethod( env, class, method, name ); logger = (*env)->NewGlobalRef( env, (*env)->CallStaticObjectMethod( env, class, method, name ) );
else else
wrn( "Couldn't initialize JNI logger." ); wrn( "Couldn't initialize JNI logger." );