From 84489e6b014be0fc620f4721d3cc1d6e663b1925 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Sun, 29 Mar 2009 14:00:46 +0200 Subject: [PATCH] java plugin: Honor the return value of `NewGlobalRef'. Apparently GCJ used to modify it's argument, but the spec apparently says that the return value is important. --- src/java.c | 47 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/src/java.c b/src/java.c index 5d131416..d0eeeff5 100644 --- a/src/java.c +++ b/src/java.c @@ -1782,7 +1782,15 @@ static cjni_callback_info_t *cjni_callback_info_create (JNIEnv *jvm_env, /* {{{ (*jvm_env)->ReleaseStringUTFChars (jvm_env, o_name, c_name); - cbi->class = (*jvm_env)->GetObjectClass (jvm_env, o_callback); + cbi->object = (*jvm_env)->NewGlobalRef (jvm_env, o_callback); + if (cbi->object == NULL) + { + ERROR ("java plugin: cjni_callback_info_create: NewGlobalRef failed."); + free (cbi); + return (NULL); + } + + cbi->class = (*jvm_env)->GetObjectClass (jvm_env, cbi->object); if (cbi->class == NULL) { ERROR ("java plugin: cjni_callback_info_create: GetObjectClass failed."); @@ -1790,8 +1798,6 @@ static cjni_callback_info_t *cjni_callback_info_create (JNIEnv *jvm_env, /* {{{ return (NULL); } - cbi->object = o_callback; - cbi->method = (*jvm_env)->GetMethodID (jvm_env, cbi->class, method_name, method_signature); if (cbi->method == NULL) @@ -1803,8 +1809,6 @@ static cjni_callback_info_t *cjni_callback_info_create (JNIEnv *jvm_env, /* {{{ return (NULL); } - (*jvm_env)->NewGlobalRef (jvm_env, o_callback); - return (cbi); } /* }}} cjni_callback_info_t cjni_callback_info_create */ @@ -2141,6 +2145,7 @@ static int cjni_config_load_plugin (oconfig_item_t *ci) /* {{{ */ JNIEnv *jvm_env; java_plugin_class_t *class; jmethodID constructor_id; + jobject tmp_object; if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { @@ -2198,8 +2203,12 @@ static int cjni_config_load_plugin (oconfig_item_t *ci) /* {{{ */ return (-1); } - class->object = (*jvm_env)->NewObject (jvm_env, class->class, + tmp_object = (*jvm_env)->NewObject (jvm_env, class->class, constructor_id); + if (tmp_object != NULL) + class->object = (*jvm_env)->NewGlobalRef (jvm_env, tmp_object); + else + class->object = NULL; if (class->object == NULL) { ERROR ("java plugin: cjni_config_load_plugin: " @@ -2210,7 +2219,6 @@ static int cjni_config_load_plugin (oconfig_item_t *ci) /* {{{ */ return (-1); } - (*jvm_env)->NewGlobalRef (jvm_env, class->object); cjni_thread_detach (); java_classes_list_len++; @@ -2227,6 +2235,9 @@ static int cjni_config_plugin_block (oconfig_item_t *ci) /* {{{ */ int status; size_t i; + jclass class; + jmethodID method; + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { WARNING ("java plugin: `Plugin' blocks " @@ -2272,8 +2283,12 @@ static int cjni_config_plugin_block (oconfig_item_t *ci) /* {{{ */ return (-1); } + class = (*jvm_env)->GetObjectClass (jvm_env, cbi->object); + method = (*jvm_env)->GetMethodID (jvm_env, class, + "config", "(Lorg/collectd/api/OConfigItem;)I"); + status = (*jvm_env)->CallIntMethod (jvm_env, - cbi->object, cbi->method, o_ocitem); + cbi->object, method, o_ocitem); (*jvm_env)->DeleteLocalRef (jvm_env, o_ocitem); cjni_thread_detach (); @@ -2611,6 +2626,7 @@ static int cjni_match_target_create (const oconfig_item_t *ci, /* {{{ */ cjni_callback_info_t *cbi_factory; const char *name; jobject o_ci; + jobject o_tmp; int type; size_t i; @@ -2712,14 +2728,21 @@ static int cjni_match_target_create (const oconfig_item_t *ci, /* {{{ */ } /* Then call the factory method so it creates a new object for us. */ - cbi_ret->object = (*jvm_env)->CallObjectMethod (jvm_env, + o_tmp = (*jvm_env)->CallObjectMethod (jvm_env, cbi_factory->object, cbi_factory->method, o_ci); - if (cbi_ret->object == NULL) + if (o_tmp == NULL) { ERROR ("java plugin: cjni_match_target_create: CallObjectMethod failed."); BAIL_OUT (-1); } + cbi_ret->object = (*jvm_env)->NewGlobalRef (jvm_env, o_tmp); + if (o_tmp == NULL) + { + ERROR ("java plugin: cjni_match_target_create: NewGlobalRef failed."); + BAIL_OUT (-1); + } + /* This is the class of the match. It is possibly different from the class of * the match-factory! */ cbi_ret->class = (*jvm_env)->GetObjectClass (jvm_env, cbi_ret->object); @@ -2739,10 +2762,6 @@ static int cjni_match_target_create (const oconfig_item_t *ci, /* {{{ */ BAIL_OUT (-1); } - /* We have everything we hoped for. Now we add a new global reference so this - * match isn't freed immediately after we return.. */ - (*jvm_env)->NewGlobalRef (jvm_env, cbi_ret->object); - /* Return the newly created match via the user_data pointer. */ *user_data = (void *) cbi_ret; -- 2.11.0