X-Git-Url: https://git.octo.it/?p=collectd.git;a=blobdiff_plain;f=src%2Fjava.c;h=a8ffd8e3ddc158c83b0b9792ff859681b55e5445;hp=20523f90b464f674b27b59944ac97edd81fa34af;hb=61a1fa91ba73e4fe3a34949f77c5f017056f2b7a;hpb=b423bd090e6a1af51446ad6967d5016045bd6ea5 diff --git a/src/java.c b/src/java.c index 20523f90..a8ffd8e3 100644 --- a/src/java.c +++ b/src/java.c @@ -93,6 +93,8 @@ static cjni_callback_info_t *java_callbacks = NULL; static size_t java_callbacks_num = 0; static pthread_mutex_t java_callbacks_lock = PTHREAD_MUTEX_INITIALIZER; +static oconfig_item_t *config_block = NULL; + /* * Prototypes * @@ -227,7 +229,7 @@ static jobject ctoj_jlong_to_number (JNIEnv *jvm_env, jlong value) /* {{{ */ jmethodID m_long_constructor; /* Look up the java.lang.Long class */ - c_long = (*jvm_env)->FindClass (jvm_env, "java.lang.Long"); + c_long = (*jvm_env)->FindClass (jvm_env, "java/lang/Long"); if (c_long == NULL) { ERROR ("java plugin: ctoj_jlong_to_number: Looking up the " @@ -255,7 +257,7 @@ static jobject ctoj_jdouble_to_number (JNIEnv *jvm_env, jdouble value) /* {{{ */ jmethodID m_double_constructor; /* Look up the java.lang.Long class */ - c_double = (*jvm_env)->FindClass (jvm_env, "java.lang.Double"); + c_double = (*jvm_env)->FindClass (jvm_env, "java/lang/Double"); if (c_double == NULL) { ERROR ("java plugin: ctoj_jdouble_to_number: Looking up the " @@ -284,6 +286,10 @@ static jobject ctoj_value_to_number (JNIEnv *jvm_env, /* {{{ */ return (ctoj_jlong_to_number (jvm_env, (jlong) value.counter)); else if (ds_type == DS_TYPE_GAUGE) return (ctoj_jdouble_to_number (jvm_env, (jdouble) value.gauge)); + if (ds_type == DS_TYPE_DERIVE) + return (ctoj_jlong_to_number (jvm_env, (jlong) value.derive)); + if (ds_type == DS_TYPE_ABSOLUTE) + return (ctoj_jlong_to_number (jvm_env, (jlong) value.absolute)); else return (NULL); } /* }}} jobject ctoj_value_to_number */ @@ -608,7 +614,7 @@ static jobject ctoj_data_set (JNIEnv *jvm_env, const data_set_t *ds) /* {{{ */ /* Search for the `DataSet (String type)' constructor. */ m_constructor = (*jvm_env)->GetMethodID (jvm_env, - c_dataset, "", "(Ljava.lang.String;)V"); + c_dataset, "", "(Ljava/lang/String;)V"); if (m_constructor == NULL) { ERROR ("java plugin: ctoj_data_set: Looking up the " @@ -1042,33 +1048,39 @@ static int jtoc_value (JNIEnv *jvm_env, /* {{{ */ class_ptr = (*jvm_env)->GetObjectClass (jvm_env, object_ptr); - if (ds_type == DS_TYPE_COUNTER) + if (ds_type == DS_TYPE_GAUGE) { - jlong tmp_long; + jdouble tmp_double; - status = jtoc_long (jvm_env, &tmp_long, - class_ptr, object_ptr, "longValue"); + status = jtoc_double (jvm_env, &tmp_double, + class_ptr, object_ptr, "doubleValue"); if (status != 0) { ERROR ("java plugin: jtoc_value: " - "jtoc_long failed."); + "jtoc_double failed."); return (-1); } - (*ret_value).counter = (counter_t) tmp_long; + (*ret_value).gauge = (gauge_t) tmp_double; } else { - jdouble tmp_double; + jlong tmp_long; - status = jtoc_double (jvm_env, &tmp_double, - class_ptr, object_ptr, "doubleValue"); + status = jtoc_long (jvm_env, &tmp_long, + class_ptr, object_ptr, "longValue"); if (status != 0) { ERROR ("java plugin: jtoc_value: " - "jtoc_double failed."); + "jtoc_long failed."); return (-1); } - (*ret_value).gauge = (gauge_t) tmp_double; + + if (ds_type == DS_TYPE_DERIVE) + (*ret_value).derive = (derive_t) tmp_long; + else if (ds_type == DS_TYPE_ABSOLUTE) + (*ret_value).absolute = (absolute_t) tmp_long; + else + (*ret_value).counter = (counter_t) tmp_long; } return (0); @@ -1407,7 +1419,7 @@ static jint JNICALL cjni_api_register_read (JNIEnv *jvm_env, /* {{{ */ ud.data = (void *) cbi; ud.free_func = cjni_callback_info_destroy; - plugin_register_complex_read (cbi->name, cjni_read, + plugin_register_complex_read (/* group = */ NULL, cbi->name, cjni_read, /* interval = */ NULL, &ud); (*jvm_env)->DeleteLocalRef (jvm_env, o_read); @@ -1919,7 +1931,9 @@ static int cjni_init_native (JNIEnv *jvm_env) /* {{{ */ api_class_ptr = (*jvm_env)->FindClass (jvm_env, "org/collectd/api/Collectd"); if (api_class_ptr == NULL) { - ERROR ("cjni_init_native: Cannot find API class `org/collectd/api/Collectd'."); + ERROR ("cjni_init_native: Cannot find the API class \"org.collectd.api" + ".Collectd\". Please set the correct class path " + "using 'JVMArg \"-Djava.class.path=...\"'."); return (-1); } @@ -2179,6 +2193,15 @@ static int cjni_config_load_plugin (oconfig_item_t *ci) /* {{{ */ class->class = NULL; class->object = NULL; + { /* Replace all dots ('.') with slashes ('/'). Dots are usually used + thorough the Java community, but (Sun's) `FindClass' and friends need + slashes. */ + size_t i; + for (i = 0; class->name[i] != 0; i++) + if (class->name[i] == '.') + class->name[i] = '/'; + } + DEBUG ("java plugin: Loading class %s", class->name); class->class = (*jvm_env)->FindClass (jvm_env, class->name); @@ -2232,7 +2255,6 @@ static int cjni_config_plugin_block (oconfig_item_t *ci) /* {{{ */ cjni_callback_info_t *cbi; jobject o_ocitem; const char *name; - int status; size_t i; jclass class; @@ -2287,7 +2309,7 @@ static int cjni_config_plugin_block (oconfig_item_t *ci) /* {{{ */ method = (*jvm_env)->GetMethodID (jvm_env, class, "config", "(Lorg/collectd/api/OConfigItem;)I"); - status = (*jvm_env)->CallIntMethod (jvm_env, + (*jvm_env)->CallIntMethod (jvm_env, cbi->object, method, o_ocitem); (*jvm_env)->DeleteLocalRef (jvm_env, o_ocitem); @@ -2295,7 +2317,7 @@ static int cjni_config_plugin_block (oconfig_item_t *ci) /* {{{ */ return (0); } /* }}} int cjni_config_plugin_block */ -static int cjni_config (oconfig_item_t *ci) /* {{{ */ +static int cjni_config_perform (oconfig_item_t *ci) /* {{{ */ { int success; int errors; @@ -2350,7 +2372,56 @@ static int cjni_config (oconfig_item_t *ci) /* {{{ */ } return (0); -} /* }}} int cjni_config */ +} /* }}} int cjni_config_perform */ + +/* Copy the children of `ci' to the global `config_block' variable. */ +static int cjni_config_callback (oconfig_item_t *ci) /* {{{ */ +{ + oconfig_item_t *ci_copy; + oconfig_item_t *tmp; + + assert (ci != NULL); + if (ci->children_num == 0) + return (0); /* nothing to do */ + + ci_copy = oconfig_clone (ci); + if (ci_copy == NULL) + { + ERROR ("java plugin: oconfig_clone failed."); + return (-1); + } + + if (config_block == NULL) + { + config_block = ci_copy; + return (0); + } + + tmp = realloc (config_block->children, + (config_block->children_num + ci_copy->children_num) * sizeof (*tmp)); + if (tmp == NULL) + { + ERROR ("java plugin: realloc failed."); + oconfig_free (ci_copy); + return (-1); + } + config_block->children = tmp; + + /* Copy the pointers */ + memcpy (config_block->children + config_block->children_num, + ci_copy->children, + ci_copy->children_num * sizeof (*ci_copy->children)); + config_block->children_num += ci_copy->children_num; + + /* Delete the pointers from the copy, so `oconfig_free' can't free them. */ + memset (ci_copy->children, 0, + ci_copy->children_num * sizeof (*ci_copy->children)); + ci_copy->children_num = 0; + + oconfig_free (ci_copy); + + return (0); +} /* }}} int cjni_config_callback */ /* Free the data contained in the `user_data_t' pointer passed to `cjni_read' * and `cjni_write'. In particular, delete the global reference to the Java @@ -2986,6 +3057,21 @@ static int cjni_init (void) /* {{{ */ { JNIEnv *jvm_env; + if ((config_block == NULL) && (jvm == NULL)) + { + ERROR ("java plugin: cjni_init: No configuration block for " + "the java plugin was found."); + return (-1); + } + + if (config_block != NULL) + { + + cjni_config_perform (config_block); + oconfig_free (config_block); + config_block = NULL; + } + if (jvm == NULL) { ERROR ("java plugin: cjni_init: jvm == NULL"); @@ -3004,7 +3090,7 @@ static int cjni_init (void) /* {{{ */ void module_register (void) { - plugin_register_complex_config ("java", cjni_config); + plugin_register_complex_config ("java", cjni_config_callback); plugin_register_init ("java", cjni_init); plugin_register_shutdown ("java", cjni_shutdown); } /* void module_register (void) */