2 * collectd - src/java.c
3 * Copyright (C) 2009 Florian octo Forster
4 * Copyright (C) 2008 Justo Alonso Achaques
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; only version 2 of the License is applicable.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 * Florian octo Forster <octo at verplant.org>
21 * Justo Alonso Achaques <justo.alonso at gmail.com>
31 #if !defined(JNI_VERSION_1_2)
32 # error "Need JNI 1.2 compatible interface!"
38 struct java_plugin_s /* {{{ */
46 #define CJNI_FLAG_ENABLED 0x0001
55 typedef struct java_plugin_s java_plugin_t;
58 struct cjni_jvm_env_s /* {{{ */
61 int reference_counter;
63 typedef struct cjni_jvm_env_s cjni_jvm_env_t;
69 static JavaVM *jvm = NULL;
70 static pthread_key_t jvm_env_key;
72 static char **jvm_argv = NULL;
73 static size_t jvm_argc = 0;
75 static java_plugin_t *java_plugins = NULL;
76 static size_t java_plugins_num = 0;
79 * C to Java conversion functions
81 static int ctoj_string (JNIEnv *jvm_env, /* {{{ */
83 jclass class_ptr, jobject object_ptr, const char *method_name)
88 /* Create a java.lang.String */
89 o_string = (*jvm_env)->NewStringUTF (jvm_env,
90 (string != NULL) ? string : "");
93 ERROR ("java plugin: ctoj_string: NewStringUTF failed.");
97 /* Search for the `void setFoo (String s)' method. */
98 m_set = (*jvm_env)->GetMethodID (jvm_env, class_ptr,
99 method_name, "(Ljava/lang/String;)V");
102 ERROR ("java plugin: ctoj_string: Cannot find method `void %s (String)'.",
104 (*jvm_env)->DeleteLocalRef (jvm_env, o_string);
108 /* Call the method. */
109 (*jvm_env)->CallVoidMethod (jvm_env, object_ptr, m_set, o_string);
111 /* Decrease reference counter on the java.lang.String object. */
112 (*jvm_env)->DeleteLocalRef (jvm_env, o_string);
114 DEBUG ("java plugin: ctoj_string: ->%s (%s);",
115 method_name, (string != NULL) ? string : "");
118 } /* }}} int ctoj_string */
120 static int ctoj_int (JNIEnv *jvm_env, /* {{{ */
122 jclass class_ptr, jobject object_ptr, const char *method_name)
126 /* Search for the `void setFoo (int i)' method. */
127 m_set = (*jvm_env)->GetMethodID (jvm_env, class_ptr,
128 method_name, "(I)V");
131 ERROR ("java plugin: ctoj_int: Cannot find method `void %s (int)'.",
136 (*jvm_env)->CallVoidMethod (jvm_env, object_ptr, m_set, value);
138 DEBUG ("java plugin: ctoj_int: ->%s (%i);",
139 method_name, (int) value);
142 } /* }}} int ctoj_int */
144 static int ctoj_long (JNIEnv *jvm_env, /* {{{ */
146 jclass class_ptr, jobject object_ptr, const char *method_name)
150 /* Search for the `void setFoo (long l)' method. */
151 m_set = (*jvm_env)->GetMethodID (jvm_env, class_ptr,
152 method_name, "(J)V");
155 ERROR ("java plugin: ctoj_long: Cannot find method `void %s (long)'.",
160 (*jvm_env)->CallVoidMethod (jvm_env, object_ptr, m_set, value);
162 DEBUG ("java plugin: ctoj_long: ->%s (%"PRIi64");",
163 method_name, (int64_t) value);
166 } /* }}} int ctoj_long */
168 static int ctoj_double (JNIEnv *jvm_env, /* {{{ */
170 jclass class_ptr, jobject object_ptr, const char *method_name)
174 /* Search for the `void setFoo (double d)' method. */
175 m_set = (*jvm_env)->GetMethodID (jvm_env, class_ptr,
176 method_name, "(D)V");
179 ERROR ("java plugin: ctoj_double: Cannot find method `void %s (double)'.",
184 (*jvm_env)->CallVoidMethod (jvm_env, object_ptr, m_set, value);
186 DEBUG ("java plugin: ctoj_double: ->%s (%g);",
187 method_name, (double) value);
190 } /* }}} int ctoj_double */
192 /* Convert a jlong to a java.lang.Number */
193 static jobject ctoj_jlong_to_number (JNIEnv *jvm_env, jlong value) /* {{{ */
196 jmethodID m_long_constructor;
198 /* Look up the java.lang.Long class */
199 c_long = (*jvm_env)->FindClass (jvm_env, "java.lang.Long");
202 ERROR ("java plugin: ctoj_jlong_to_number: Looking up the "
203 "java.lang.Long class failed.");
207 m_long_constructor = (*jvm_env)->GetMethodID (jvm_env,
208 c_long, "<init>", "(J)V");
209 if (m_long_constructor == NULL)
211 ERROR ("java plugin: ctoj_jlong_to_number: Looking up the "
212 "`Long (long)' constructor failed.");
216 return ((*jvm_env)->NewObject (jvm_env,
217 c_long, m_long_constructor, value));
218 } /* }}} jobject ctoj_jlong_to_number */
220 /* Convert a jdouble to a java.lang.Number */
221 static jobject ctoj_jdouble_to_number (JNIEnv *jvm_env, jdouble value) /* {{{ */
224 jmethodID m_double_constructor;
226 /* Look up the java.lang.Long class */
227 c_double = (*jvm_env)->FindClass (jvm_env, "java.lang.Double");
228 if (c_double == NULL)
230 ERROR ("java plugin: ctoj_jdouble_to_number: Looking up the "
231 "java.lang.Double class failed.");
235 m_double_constructor = (*jvm_env)->GetMethodID (jvm_env,
236 c_double, "<init>", "(D)V");
237 if (m_double_constructor == NULL)
239 ERROR ("java plugin: ctoj_jdouble_to_number: Looking up the "
240 "`Double (double)' constructor failed.");
244 return ((*jvm_env)->NewObject (jvm_env,
245 c_double, m_double_constructor, value));
246 } /* }}} jobject ctoj_jdouble_to_number */
248 /* Convert a value_t to a java.lang.Number */
249 static jobject ctoj_value_to_number (JNIEnv *jvm_env, /* {{{ */
250 value_t value, int ds_type)
252 if (ds_type == DS_TYPE_COUNTER)
253 return (ctoj_jlong_to_number (jvm_env, (jlong) value.counter));
254 else if (ds_type == DS_TYPE_GAUGE)
255 return (ctoj_jdouble_to_number (jvm_env, (jdouble) value.gauge));
258 } /* }}} jobject ctoj_value_to_number */
260 /* Convert a data_source_t to a org.collectd.api.DataSource */
261 static jobject ctoj_data_source (JNIEnv *jvm_env, /* {{{ */
262 const data_source_t *dsrc)
265 jmethodID m_datasource_constructor;
266 jobject o_datasource;
269 /* Look up the DataSource class */
270 c_datasource = (*jvm_env)->FindClass (jvm_env,
271 "org.collectd.api.DataSource");
272 if (c_datasource == NULL)
274 ERROR ("java plugin: ctoj_data_source: "
275 "FindClass (org.collectd.api.DataSource) failed.");
279 /* Lookup the `ValueList ()' constructor. */
280 m_datasource_constructor = (*jvm_env)->GetMethodID (jvm_env, c_datasource,
282 if (m_datasource_constructor == NULL)
284 ERROR ("java plugin: ctoj_data_source: Cannot find the "
285 "`DataSource ()' constructor.");
289 /* Create a new instance. */
290 o_datasource = (*jvm_env)->NewObject (jvm_env, c_datasource,
291 m_datasource_constructor);
292 if (o_datasource == NULL)
294 ERROR ("java plugin: ctoj_data_source: "
295 "Creating a new DataSource instance failed.");
299 /* Set name via `void setName (String name)' */
300 status = ctoj_string (jvm_env, dsrc->name,
301 c_datasource, o_datasource, "setName");
304 ERROR ("java plugin: ctoj_data_source: "
305 "ctoj_string (setName) failed.");
306 (*jvm_env)->DeleteLocalRef (jvm_env, o_datasource);
310 /* Set type via `void setType (int type)' */
311 status = ctoj_int (jvm_env, dsrc->type,
312 c_datasource, o_datasource, "setType");
315 ERROR ("java plugin: ctoj_data_source: "
316 "ctoj_int (setType) failed.");
317 (*jvm_env)->DeleteLocalRef (jvm_env, o_datasource);
321 /* Set min via `void setMin (double min)' */
322 status = ctoj_double (jvm_env, dsrc->min,
323 c_datasource, o_datasource, "setMin");
326 ERROR ("java plugin: ctoj_data_source: "
327 "ctoj_double (setMin) failed.");
328 (*jvm_env)->DeleteLocalRef (jvm_env, o_datasource);
332 /* Set max via `void setMax (double max)' */
333 status = ctoj_double (jvm_env, dsrc->max,
334 c_datasource, o_datasource, "setMax");
337 ERROR ("java plugin: ctoj_data_source: "
338 "ctoj_double (setMax) failed.");
339 (*jvm_env)->DeleteLocalRef (jvm_env, o_datasource);
343 return (o_datasource);
344 } /* }}} jobject ctoj_data_source */
346 /* Convert a oconfig_value_t to a org.collectd.api.OConfigValue */
347 static jobject ctoj_oconfig_value (JNIEnv *jvm_env, /* {{{ */
348 oconfig_value_t ocvalue)
351 jmethodID m_ocvalue_constructor;
355 m_ocvalue_constructor = NULL;
358 c_ocvalue = (*jvm_env)->FindClass (jvm_env,
359 "org.collectd.api.OConfigValue");
360 if (c_ocvalue == NULL)
362 ERROR ("java plugin: ctoj_oconfig_value: "
363 "FindClass (org.collectd.api.OConfigValue) failed.");
367 if (ocvalue.type == OCONFIG_TYPE_BOOLEAN)
369 jboolean tmp_boolean;
371 tmp_boolean = (ocvalue.value.boolean == 0) ? JNI_FALSE : JNI_TRUE;
373 m_ocvalue_constructor = (*jvm_env)->GetMethodID (jvm_env, c_ocvalue,
375 if (m_ocvalue_constructor == NULL)
377 ERROR ("java plugin: ctoj_oconfig_value: Cannot find the "
378 "`OConfigValue (boolean)' constructor.");
382 return ((*jvm_env)->NewObject (jvm_env,
383 c_ocvalue, m_ocvalue_constructor, tmp_boolean));
384 } /* if (ocvalue.type == OCONFIG_TYPE_BOOLEAN) */
385 else if (ocvalue.type == OCONFIG_TYPE_STRING)
387 m_ocvalue_constructor = (*jvm_env)->GetMethodID (jvm_env, c_ocvalue,
388 "<init>", "(Ljava/lang/String;)V");
389 if (m_ocvalue_constructor == NULL)
391 ERROR ("java plugin: ctoj_oconfig_value: Cannot find the "
392 "`OConfigValue (String)' constructor.");
396 o_argument = (*jvm_env)->NewStringUTF (jvm_env, ocvalue.value.string);
397 if (o_argument == NULL)
399 ERROR ("java plugin: ctoj_oconfig_value: "
400 "Creating a String object failed.");
404 else if (ocvalue.type == OCONFIG_TYPE_NUMBER)
406 m_ocvalue_constructor = (*jvm_env)->GetMethodID (jvm_env, c_ocvalue,
407 "<init>", "(Ljava/lang/Number;)V");
408 if (m_ocvalue_constructor == NULL)
410 ERROR ("java plugin: ctoj_oconfig_value: Cannot find the "
411 "`OConfigValue (Number)' constructor.");
415 o_argument = ctoj_jdouble_to_number (jvm_env,
416 (jdouble) ocvalue.value.number);
417 if (o_argument == NULL)
419 ERROR ("java plugin: ctoj_oconfig_value: "
420 "Creating a Number object failed.");
429 assert (m_ocvalue_constructor != NULL);
430 assert (o_argument != NULL);
432 o_ocvalue = (*jvm_env)->NewObject (jvm_env,
433 c_ocvalue, m_ocvalue_constructor, o_argument);
434 if (o_ocvalue == NULL)
436 ERROR ("java plugin: ctoj_oconfig_value: "
437 "Creating an OConfigValue object failed.");
438 (*jvm_env)->DeleteLocalRef (jvm_env, o_argument);
442 (*jvm_env)->DeleteLocalRef (jvm_env, o_argument);
444 } /* }}} jobject ctoj_oconfig_value */
446 /* Convert a oconfig_item_t to a org.collectd.api.OConfigItem */
447 static jobject ctoj_oconfig_item (JNIEnv *jvm_env, /* {{{ */
448 const oconfig_item_t *ci)
451 jmethodID m_ocitem_constructor;
452 jmethodID m_addvalue;
453 jmethodID m_addchild;
458 c_ocitem = (*jvm_env)->FindClass (jvm_env, "org.collectd.api.OConfigItem");
459 if (c_ocitem == NULL)
461 ERROR ("java plugin: ctoj_oconfig_item: "
462 "FindClass (org.collectd.api.OConfigItem) failed.");
466 /* Get the required methods: m_ocitem_constructor, m_addvalue, and m_addchild
468 m_ocitem_constructor = (*jvm_env)->GetMethodID (jvm_env, c_ocitem,
469 "<init>", "(Ljava/lang/String;)V");
470 if (m_ocitem_constructor == NULL)
472 ERROR ("java plugin: ctoj_oconfig_item: Cannot find the "
473 "`OConfigItem (String)' constructor.");
477 m_addvalue = (*jvm_env)->GetMethodID (jvm_env, c_ocitem,
478 "addValue", "(Lorg/collectd/api/OConfigValue;)V");
479 if (m_addvalue == NULL)
481 ERROR ("java plugin: ctoj_oconfig_item: Cannot find the "
482 "`addValue (OConfigValue)' method.");
486 m_addchild = (*jvm_env)->GetMethodID (jvm_env, c_ocitem,
487 "addChild", "(Lorg/collectd/api/OConfigItem;)V");
488 if (m_addchild == NULL)
490 ERROR ("java plugin: ctoj_oconfig_item: Cannot find the "
491 "`addChild (OConfigItem)' method.");
496 /* Create a String object with the key.
497 * Needed for calling the constructor. */
498 o_key = (*jvm_env)->NewStringUTF (jvm_env, ci->key);
501 ERROR ("java plugin: ctoj_oconfig_item: "
502 "Creating String object failed.");
506 /* Create an OConfigItem object */
507 o_ocitem = (*jvm_env)->NewObject (jvm_env,
508 c_ocitem, m_ocitem_constructor, o_key);
509 if (o_ocitem == NULL)
511 ERROR ("java plugin: ctoj_oconfig_item: "
512 "Creating an OConfigItem object failed.");
513 (*jvm_env)->DeleteLocalRef (jvm_env, o_key);
517 /* We don't need the String object any longer.. */
518 (*jvm_env)->DeleteLocalRef (jvm_env, o_key);
520 /* Call OConfigItem.addValue for each value */
521 for (i = 0; i < ci->values_num; i++) /* {{{ */
525 o_value = ctoj_oconfig_value (jvm_env, ci->values[i]);
528 ERROR ("java plugin: ctoj_oconfig_item: "
529 "Creating an OConfigValue object failed.");
530 (*jvm_env)->DeleteLocalRef (jvm_env, o_ocitem);
534 (*jvm_env)->CallVoidMethod (jvm_env, o_ocitem, m_addvalue, o_value);
535 (*jvm_env)->DeleteLocalRef (jvm_env, o_value);
536 } /* }}} for (i = 0; i < ci->values_num; i++) */
538 /* Call OConfigItem.addChild for each child */
539 for (i = 0; i < ci->children_num; i++) /* {{{ */
543 o_child = ctoj_oconfig_item (jvm_env, ci->children + i);
546 ERROR ("java plugin: ctoj_oconfig_item: "
547 "Creating an OConfigItem object failed.");
548 (*jvm_env)->DeleteLocalRef (jvm_env, o_ocitem);
552 (*jvm_env)->CallVoidMethod (jvm_env, o_ocitem, m_addvalue, o_child);
553 (*jvm_env)->DeleteLocalRef (jvm_env, o_child);
554 } /* }}} for (i = 0; i < ci->children_num; i++) */
557 } /* }}} jobject ctoj_oconfig_item */
559 /* Convert a data_set_t to a java.util.List<DataSource> */
560 static jobject ctoj_data_set (JNIEnv *jvm_env, const data_set_t *ds) /* {{{ */
563 jmethodID m_constructor;
568 /* Look up the java.util.ArrayList class */
569 c_arraylist = (*jvm_env)->FindClass (jvm_env, "java.util.ArrayList");
570 if (c_arraylist == NULL)
572 ERROR ("java plugin: ctoj_data_set: Looking up the "
573 "java.util.ArrayList class failed.");
577 /* Search for the `ArrayList (int capacity)' constructor. */
578 m_constructor = (*jvm_env)->GetMethodID (jvm_env,
579 c_arraylist, "<init>", "()V");
580 if (m_constructor == NULL)
582 ERROR ("java plugin: ctoj_data_set: Looking up the "
583 "`ArrayList (void)' constructor failed.");
587 /* Search for the `boolean add (Object element)' method. */
588 m_add = (*jvm_env)->GetMethodID (jvm_env,
589 c_arraylist, "add", "(Ljava/lang/Object;)Z");
592 ERROR ("java plugin: ctoj_data_set: Looking up the "
593 "`add (Object)' method failed.");
597 o_dataset = (*jvm_env)->NewObject (jvm_env, c_arraylist, m_constructor);
598 if (o_dataset == NULL)
600 ERROR ("java plugin: ctoj_data_set: "
601 "Creating an ArrayList object failed.");
605 for (i = 0; i < ds->ds_num; i++)
607 jobject o_datasource;
610 o_datasource = ctoj_data_source (jvm_env, ds->ds + i);
611 if (o_datasource == NULL)
613 ERROR ("java plugin: ctoj_data_set: ctoj_data_source (%s.%s) failed",
614 ds->type, ds->ds[i].name);
615 (*jvm_env)->DeleteLocalRef (jvm_env, o_dataset);
619 status = (*jvm_env)->CallBooleanMethod (jvm_env,
620 o_dataset, m_add, o_datasource);
623 ERROR ("java plugin: ctoj_data_set: ArrayList.add returned FALSE.");
624 (*jvm_env)->DeleteLocalRef (jvm_env, o_datasource);
625 (*jvm_env)->DeleteLocalRef (jvm_env, o_dataset);
629 (*jvm_env)->DeleteLocalRef (jvm_env, o_datasource);
630 } /* for (i = 0; i < ds->ds_num; i++) */
633 } /* }}} jobject ctoj_data_set */
635 static int ctoj_value_list_add_value (JNIEnv *jvm_env, /* {{{ */
636 value_t value, int ds_type,
637 jclass class_ptr, jobject object_ptr)
639 jmethodID m_addvalue;
642 m_addvalue = (*jvm_env)->GetMethodID (jvm_env, class_ptr,
643 "addValue", "(Ljava/lang/Number;)V");
644 if (m_addvalue == NULL)
646 ERROR ("java plugin: ctoj_value_list_add_value: "
647 "Cannot find method `void addValue (Number)'.");
651 o_number = ctoj_value_to_number (jvm_env, value, ds_type);
652 if (o_number == NULL)
654 ERROR ("java plugin: ctoj_value_list_add_value: "
655 "ctoj_value_to_number failed.");
659 (*jvm_env)->CallVoidMethod (jvm_env, object_ptr, m_addvalue, o_number);
661 (*jvm_env)->DeleteLocalRef (jvm_env, o_number);
664 } /* }}} int ctoj_value_list_add_value */
666 static int ctoj_value_list_add_data_set (JNIEnv *jvm_env, /* {{{ */
667 jclass c_valuelist, jobject o_valuelist, const data_set_t *ds)
669 jmethodID m_setdatasource;
672 /* Look for the `void setDataSource (List<DataSource> ds)' method. */
673 m_setdatasource = (*jvm_env)->GetMethodID (jvm_env, c_valuelist,
674 "setDataSource", "(Ljava/util/List;)V");
675 if (m_setdatasource == NULL)
677 ERROR ("java plugin: ctoj_value_list_add_data_set: "
678 "Cannot find the `void setDataSource (List<DataSource> ds)' method.");
682 /* Create a List<DataSource> object. */
683 o_dataset = ctoj_data_set (jvm_env, ds);
684 if (o_dataset == NULL)
686 ERROR ("java plugin: ctoj_value_list_add_data_set: "
687 "ctoj_data_set (%s) failed.", ds->type);
691 /* Actually call the method. */
692 (*jvm_env)->CallVoidMethod (jvm_env,
693 o_valuelist, m_setdatasource, o_dataset);
695 /* Decrease reference counter on the List<DataSource> object. */
696 (*jvm_env)->DeleteLocalRef (jvm_env, o_dataset);
699 } /* }}} int ctoj_value_list_add_data_set */
701 static jobject ctoj_value_list (JNIEnv *jvm_env, /* {{{ */
702 const data_set_t *ds, const value_list_t *vl)
705 jmethodID m_valuelist_constructor;
710 /* First, create a new ValueList instance..
711 * Look up the class.. */
712 c_valuelist = (*jvm_env)->FindClass (jvm_env,
713 "org.collectd.api.ValueList");
714 if (c_valuelist == NULL)
716 ERROR ("java plugin: ctoj_value_list: "
717 "FindClass (org.collectd.api.ValueList) failed.");
721 /* Lookup the `ValueList ()' constructor. */
722 m_valuelist_constructor = (*jvm_env)->GetMethodID (jvm_env, c_valuelist,
724 if (m_valuelist_constructor == NULL)
726 ERROR ("java plugin: ctoj_value_list: Cannot find the "
727 "`ValueList ()' constructor.");
731 /* Create a new instance. */
732 o_valuelist = (*jvm_env)->NewObject (jvm_env, c_valuelist,
733 m_valuelist_constructor);
734 if (o_valuelist == NULL)
736 ERROR ("java plugin: ctoj_value_list: Creating a new ValueList instance "
741 status = ctoj_value_list_add_data_set (jvm_env,
742 c_valuelist, o_valuelist, ds);
745 ERROR ("java plugin: ctoj_value_list: "
746 "ctoj_value_list_add_data_set failed.");
747 (*jvm_env)->DeleteLocalRef (jvm_env, o_valuelist);
751 /* Set the strings.. */
752 #define SET_STRING(str,method_name) do { \
753 status = ctoj_string (jvm_env, str, \
754 c_valuelist, o_valuelist, method_name); \
756 ERROR ("java plugin: ctoj_value_list: jtoc_string (%s) failed.", \
758 (*jvm_env)->DeleteLocalRef (jvm_env, o_valuelist); \
762 SET_STRING (vl->host, "setHost");
763 SET_STRING (vl->plugin, "setPlugin");
764 SET_STRING (vl->plugin_instance, "setPluginInstance");
765 SET_STRING (vl->type, "setType");
766 SET_STRING (vl->type_instance, "setTypeInstance");
770 /* Set the `time' member. Java stores time in milliseconds. */
771 status = ctoj_long (jvm_env, ((jlong) vl->time) * ((jlong) 1000),
772 c_valuelist, o_valuelist, "setTime");
775 ERROR ("java plugin: ctoj_value_list: ctoj_long (setTime) failed.");
776 (*jvm_env)->DeleteLocalRef (jvm_env, o_valuelist);
780 /* Set the `interval' member.. */
781 status = ctoj_long (jvm_env, (jlong) vl->interval,
782 c_valuelist, o_valuelist, "setInterval");
785 ERROR ("java plugin: ctoj_value_list: ctoj_long (setInterval) failed.");
786 (*jvm_env)->DeleteLocalRef (jvm_env, o_valuelist);
790 for (i = 0; i < vl->values_len; i++)
792 status = ctoj_value_list_add_value (jvm_env, vl->values[i], ds->ds[i].type,
793 c_valuelist, o_valuelist);
796 ERROR ("java plugin: ctoj_value_list: "
797 "ctoj_value_list_add_value failed.");
798 (*jvm_env)->DeleteLocalRef (jvm_env, o_valuelist);
803 return (o_valuelist);
804 } /* }}} int ctoj_value_list */
807 * Java to C conversion functions
809 static int jtoc_string (JNIEnv *jvm_env, /* {{{ */
810 char *buffer, size_t buffer_size,
811 jclass class_ptr, jobject object_ptr, const char *method_name)
817 method_id = (*jvm_env)->GetMethodID (jvm_env, class_ptr,
818 method_name, "()Ljava/lang/String;");
819 if (method_id == NULL)
821 ERROR ("java plugin: jtoc_string: Cannot find method `String %s ()'.",
826 string_obj = (*jvm_env)->CallObjectMethod (jvm_env, object_ptr, method_id);
827 if (string_obj == NULL)
829 ERROR ("java plugin: jtoc_string: CallObjectMethod (%s) failed.",
834 c_str = (*jvm_env)->GetStringUTFChars (jvm_env, string_obj, 0);
837 ERROR ("java plugin: jtoc_string: GetStringUTFChars failed.");
838 (*jvm_env)->DeleteLocalRef (jvm_env, string_obj);
842 DEBUG ("java plugin: jtoc_string: ->%s() = %s", method_name, c_str);
844 sstrncpy (buffer, c_str, buffer_size);
846 (*jvm_env)->ReleaseStringUTFChars (jvm_env, string_obj, c_str);
847 (*jvm_env)->DeleteLocalRef (jvm_env, string_obj);
850 } /* }}} int jtoc_string */
852 static int jtoc_long (JNIEnv *jvm_env, /* {{{ */
854 jclass class_ptr, jobject object_ptr, const char *method_name)
858 method_id = (*jvm_env)->GetMethodID (jvm_env, class_ptr,
860 if (method_id == NULL)
862 ERROR ("java plugin: jtoc_long: Cannot find method `long %s ()'.",
867 *ret_value = (*jvm_env)->CallLongMethod (jvm_env, object_ptr, method_id);
869 DEBUG ("java plugin: jtoc_long: ->%s() = %li",
870 method_name, (long int) *ret_value);
873 } /* }}} int jtoc_long */
875 static int jtoc_double (JNIEnv *jvm_env, /* {{{ */
877 jclass class_ptr, jobject object_ptr, const char *method_name)
881 method_id = (*jvm_env)->GetMethodID (jvm_env, class_ptr,
883 if (method_id == NULL)
885 ERROR ("java plugin: jtoc_string: Cannot find method `double %s ()'.",
890 *ret_value = (*jvm_env)->CallDoubleMethod (jvm_env, object_ptr, method_id);
892 DEBUG ("java plugin: jtoc_double: ->%s() = %g",
893 method_name, (double) *ret_value);
896 } /* }}} int jtoc_double */
898 static int jtoc_value (JNIEnv *jvm_env, /* {{{ */
899 value_t *ret_value, int ds_type, jobject object_ptr)
904 class_ptr = (*jvm_env)->GetObjectClass (jvm_env, object_ptr);
906 if (ds_type == DS_TYPE_COUNTER)
910 status = jtoc_long (jvm_env, &tmp_long,
911 class_ptr, object_ptr, "longValue");
914 ERROR ("java plugin: jtoc_value: "
915 "jtoc_long failed.");
918 (*ret_value).counter = (counter_t) tmp_long;
924 status = jtoc_double (jvm_env, &tmp_double,
925 class_ptr, object_ptr, "doubleValue");
928 ERROR ("java plugin: jtoc_value: "
929 "jtoc_double failed.");
932 (*ret_value).gauge = (gauge_t) tmp_double;
936 } /* }}} int jtoc_value */
938 static int jtoc_values_array (JNIEnv *jvm_env, /* {{{ */
939 const data_set_t *ds, value_list_t *vl,
940 jclass class_ptr, jobject object_ptr)
942 jmethodID m_getvalues;
945 jobjectArray o_number_array;
951 values_num = ds->ds_num;
954 o_number_array = NULL;
957 #define BAIL_OUT(status) \
959 if (o_number_array != NULL) \
960 (*jvm_env)->DeleteLocalRef (jvm_env, o_number_array); \
961 if (o_list != NULL) \
962 (*jvm_env)->DeleteLocalRef (jvm_env, o_list); \
965 /* Call: List<Number> ValueList.getValues () */
966 m_getvalues = (*jvm_env)->GetMethodID (jvm_env, class_ptr,
967 "getValues", "()Ljava/util/List;");
968 if (m_getvalues == NULL)
970 ERROR ("java plugin: jtoc_values_array: "
971 "Cannot find method `List getValues ()'.");
975 o_list = (*jvm_env)->CallObjectMethod (jvm_env, object_ptr, m_getvalues);
978 ERROR ("java plugin: jtoc_values_array: "
979 "CallObjectMethod (getValues) failed.");
983 /* Call: Number[] List.toArray () */
984 m_toarray = (*jvm_env)->GetMethodID (jvm_env,
985 (*jvm_env)->GetObjectClass (jvm_env, o_list),
986 "toArray", "()[Ljava/lang/Object;");
987 if (m_toarray == NULL)
989 ERROR ("java plugin: jtoc_values_array: "
990 "Cannot find method `Object[] toArray ()'.");
994 o_number_array = (*jvm_env)->CallObjectMethod (jvm_env, o_list, m_toarray);
995 if (o_number_array == NULL)
997 ERROR ("java plugin: jtoc_values_array: "
998 "CallObjectMethod (toArray) failed.");
1002 values = calloc (values_num, sizeof (value_t));
1005 ERROR ("java plugin: jtoc_values_array: calloc failed.");
1009 for (i = 0; i < values_num; i++)
1014 o_number = (*jvm_env)->GetObjectArrayElement (jvm_env,
1015 o_number_array, (jsize) i);
1016 if (o_number == NULL)
1018 ERROR ("java plugin: jtoc_values_array: "
1019 "GetObjectArrayElement (%i) failed.", i);
1023 status = jtoc_value (jvm_env, values + i, ds->ds[i].type, o_number);
1026 ERROR ("java plugin: jtoc_values_array: "
1027 "jtoc_value (%i) failed.", i);
1030 } /* for (i = 0; i < values_num; i++) */
1032 vl->values = values;
1033 vl->values_len = values_num;
1036 (*jvm_env)->DeleteLocalRef (jvm_env, o_number_array);
1037 (*jvm_env)->DeleteLocalRef (jvm_env, o_list);
1039 } /* }}} int jtoc_values_array */
1041 /* Convert a org.collectd.api.ValueList to a value_list_t. */
1042 static int jtoc_value_list (JNIEnv *jvm_env, value_list_t *vl, /* {{{ */
1048 const data_set_t *ds;
1050 class_ptr = (*jvm_env)->GetObjectClass (jvm_env, object_ptr);
1051 if (class_ptr == NULL)
1053 ERROR ("java plugin: jtoc_value_list: GetObjectClass failed.");
1057 #define SET_STRING(buffer,method) do { \
1058 status = jtoc_string (jvm_env, buffer, sizeof (buffer), \
1059 class_ptr, object_ptr, method); \
1060 if (status != 0) { \
1061 ERROR ("java plugin: jtoc_value_list: jtoc_string (%s) failed.", \
1066 SET_STRING(vl->type, "getType");
1068 ds = plugin_get_ds (vl->type);
1071 ERROR ("java plugin: jtoc_value_list: Data-set `%s' is not defined. "
1072 "Please consult the types.db(5) manpage for mor information.",
1077 SET_STRING(vl->host, "getHost");
1078 SET_STRING(vl->plugin, "getPlugin");
1079 SET_STRING(vl->plugin_instance, "getPluginInstance");
1080 SET_STRING(vl->type_instance, "getTypeInstance");
1084 status = jtoc_long (jvm_env, &tmp_long, class_ptr, object_ptr, "getTime");
1087 ERROR ("java plugin: jtoc_value_list: jtoc_long (getTime) failed.");
1090 /* Java measures time in milliseconds. */
1091 vl->time = (time_t) (tmp_long / ((jlong) 1000));
1093 status = jtoc_long (jvm_env, &tmp_long,
1094 class_ptr, object_ptr, "getInterval");
1097 ERROR ("java plugin: jtoc_value_list: jtoc_long (getInterval) failed.");
1100 vl->interval = (int) tmp_long;
1102 status = jtoc_values_array (jvm_env, ds, vl, class_ptr, object_ptr);
1105 ERROR ("java plugin: jtoc_value_list: jtoc_values_array failed.");
1110 } /* }}} int jtoc_value_list */
1113 * Functions accessible from Java
1115 static jint JNICALL cjni_api_dispatch_values (JNIEnv *jvm_env, /* {{{ */
1116 jobject this, jobject java_vl)
1118 value_list_t vl = VALUE_LIST_INIT;
1121 DEBUG ("cjni_api_dispatch_values: java_vl = %p;", (void *) java_vl);
1123 status = jtoc_value_list (jvm_env, &vl, java_vl);
1126 ERROR ("java plugin: cjni_api_dispatch_values: jtoc_value_list failed.");
1130 status = plugin_dispatch_values (&vl);
1135 } /* }}} jint cjni_api_dispatch_values */
1137 static jobject JNICALL cjni_api_get_ds (JNIEnv *jvm_env, /* {{{ */
1138 jobject this, jobject o_string_type)
1140 const char *ds_name;
1141 const data_set_t *ds;
1144 ds_name = (*jvm_env)->GetStringUTFChars (jvm_env, o_string_type, 0);
1145 if (ds_name == NULL)
1147 ERROR ("java plugin: cjni_api_get_ds: GetStringUTFChars failed.");
1151 ds = plugin_get_ds (ds_name);
1152 DEBUG ("java plugin: cjni_api_get_ds: "
1153 "plugin_get_ds (%s) = %p;", ds_name, (void *) ds);
1155 (*jvm_env)->ReleaseStringUTFChars (jvm_env, o_string_type, ds_name);
1160 o_dataset = ctoj_data_set (jvm_env, ds);
1162 } /* }}} jint cjni_api_get_ds */
1164 static JNINativeMethod jni_api_functions[] =
1166 { "DispatchValues", "(Lorg/collectd/api/ValueList;)I", cjni_api_dispatch_values },
1167 { "GetDS", "(Ljava/lang/String;)Ljava/util/List;", cjni_api_get_ds }
1169 static size_t jni_api_functions_num = sizeof (jni_api_functions)
1170 / sizeof (jni_api_functions[0]);
1175 static JNIEnv *cjni_thread_attach (void) /* {{{ */
1177 cjni_jvm_env_t *cjni_env;
1180 cjni_env = pthread_getspecific (jvm_env_key);
1181 if (cjni_env == NULL)
1183 /* This pointer is free'd in `cjni_jvm_env_destroy'. */
1184 cjni_env = (cjni_jvm_env_t *) malloc (sizeof (*cjni_env));
1185 if (cjni_env == NULL)
1187 ERROR ("java plugin: cjni_thread_attach: malloc failed.");
1190 memset (cjni_env, 0, sizeof (*cjni_env));
1191 cjni_env->reference_counter = 0;
1192 cjni_env->jvm_env = NULL;
1194 pthread_setspecific (jvm_env_key, cjni_env);
1197 if (cjni_env->reference_counter > 0)
1199 cjni_env->reference_counter++;
1200 jvm_env = cjni_env->jvm_env;
1205 JavaVMAttachArgs args;
1207 assert (cjni_env->jvm_env == NULL);
1209 memset (&args, 0, sizeof (args));
1210 args.version = JNI_VERSION_1_2;
1212 status = (*jvm)->AttachCurrentThread (jvm, (void *) &jvm_env, (void *) &args);
1215 ERROR ("java plugin: cjni_thread_attach: AttachCurrentThread failed "
1216 "with status %i.", status);
1220 cjni_env->reference_counter = 1;
1221 cjni_env->jvm_env = jvm_env;
1224 DEBUG ("java plugin: cjni_thread_attach: cjni_env->reference_counter = %i",
1225 cjni_env->reference_counter);
1226 assert (jvm_env != NULL);
1228 } /* }}} JNIEnv *cjni_thread_attach */
1230 static int cjni_thread_detach (void) /* {{{ */
1232 cjni_jvm_env_t *cjni_env;
1235 cjni_env = pthread_getspecific (jvm_env_key);
1236 if (cjni_env == NULL)
1238 ERROR ("java plugin: cjni_thread_detach: pthread_getspecific failed.");
1242 assert (cjni_env->reference_counter > 0);
1243 assert (cjni_env->jvm_env != NULL);
1245 cjni_env->reference_counter--;
1246 DEBUG ("java plugin: cjni_thread_detach: cjni_env->reference_counter = %i",
1247 cjni_env->reference_counter);
1249 if (cjni_env->reference_counter > 0)
1252 status = (*jvm)->DetachCurrentThread (jvm);
1255 ERROR ("java plugin: cjni_thread_detach: DetachCurrentThread failed "
1256 "with status %i.", status);
1259 cjni_env->reference_counter = 0;
1260 cjni_env->jvm_env = NULL;
1263 } /* }}} JNIEnv *cjni_thread_attach */
1265 static void cjni_jvm_env_destroy (void *args) /* {{{ */
1267 cjni_jvm_env_t *cjni_env;
1272 cjni_env = (cjni_jvm_env_t *) args;
1274 if (cjni_env->reference_counter > 0)
1276 ERROR ("java plugin: cjni_jvm_env_destroy: "
1277 "cjni_env->reference_counter = %i;", cjni_env->reference_counter);
1280 if (cjni_env->jvm_env != NULL)
1282 ERROR ("java plugin: cjni_jvm_env_destroy: cjni_env->jvm_env = %p;",
1283 (void *) cjni_env->jvm_env);
1286 /* The pointer is allocated in `cjni_thread_attach' */
1288 } /* }}} void cjni_jvm_env_destroy */
1290 static int cjni_config_add_jvm_arg (oconfig_item_t *ci) /* {{{ */
1294 if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
1296 WARNING ("java plugin: `JVMArg' needs exactly one string argument.");
1300 tmp = (char **) realloc (jvm_argv, sizeof (char *) * (jvm_argc + 1));
1303 ERROR ("java plugin: realloc failed.");
1308 jvm_argv[jvm_argc] = strdup (ci->values[0].value.string);
1309 if (jvm_argv[jvm_argc] == NULL)
1311 ERROR ("java plugin: strdup failed.");
1317 } /* }}} int cjni_config_add_jvm_arg */
1319 static int cjni_config_load_plugin (oconfig_item_t *ci) /* {{{ */
1323 if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
1325 WARNING ("java plugin: `LoadPlugin' needs exactly one string argument.");
1329 jp = (java_plugin_t *) realloc (java_plugins,
1330 sizeof (*java_plugins) * (java_plugins_num + 1));
1333 ERROR ("java plugin: realloc failed.");
1337 jp = java_plugins + java_plugins_num;
1339 memset (jp, 0, sizeof (*jp));
1340 jp->class_name = strdup (ci->values[0].value.string);
1341 if (jp->class_name == NULL)
1343 ERROR ("java plugin: strdup failed.");
1347 jp->class_ptr = NULL;
1348 jp->object_ptr = NULL;
1351 jp->m_config = NULL;
1355 jp->m_shutdown = NULL;
1360 } /* }}} int cjni_config_load_plugin */
1362 static int cjni_config_plugin_block (oconfig_item_t *ci) /* {{{ */
1365 const char *class_name;
1367 if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
1369 WARNING ("java plugin: `Plugin' blocks "
1370 "need exactly one string argument.");
1374 class_name = ci->values[0].value.string;
1375 for (i = 0; i < java_plugins_num; i++)
1376 if (strcmp (java_plugins[i].class_name, class_name) == 0)
1379 if (i >= java_plugins_num)
1381 WARNING ("java plugin: Configuration block for the `%s' plugin found, "
1382 "but the plugin has not been loaded. Please note, that the class "
1383 "name is case-sensitive!",
1388 if (java_plugins[i].ci != NULL)
1390 WARNING ("java plugin: There are more than one <Plugin> blocks for the "
1391 "`%s' plugin. This is currently not supported - only the first block "
1397 java_plugins[i].ci = oconfig_clone (ci);
1398 if (java_plugins[i].ci == NULL)
1400 ERROR ("java plugin: cjni_config_plugin_block: "
1401 "oconfig_clone failed for `%s'.",
1406 DEBUG ("java plugin: cjni_config_plugin_block: "
1407 "Successfully copied config for `%s'.",
1411 } /* }}} int cjni_config_plugin_block */
1413 static int cjni_config (oconfig_item_t *ci) /* {{{ */
1423 for (i = 0; i < ci->children_num; i++)
1425 oconfig_item_t *child = ci->children + i;
1427 if (strcasecmp ("JVMArg", child->key) == 0)
1429 status = cjni_config_add_jvm_arg (child);
1435 else if (strcasecmp ("LoadPlugin", child->key) == 0)
1437 status = cjni_config_load_plugin (child);
1443 else if (strcasecmp ("Plugin", child->key) == 0)
1445 status = cjni_config_plugin_block (child);
1453 WARNING ("java plugin: Option `%s' not allowed here.", child->key);
1458 if ((success == 0) && (errors > 0))
1460 ERROR ("java plugin: All statements failed.");
1465 } /* }}} int cjni_config */
1467 static int cjni_write_one_plugin (JNIEnv *jvm_env, /* {{{ */
1468 java_plugin_t *jp, jobject vl_java)
1473 || ((jp->flags & CJNI_FLAG_ENABLED) == 0)
1474 || (jp->m_write == NULL))
1477 DEBUG ("java plugin: Calling: %s.Write(ValueList)", jp->class_name);
1479 status = (*jvm_env)->CallIntMethod (jvm_env, jp->object_ptr,
1480 jp->m_write, vl_java);
1483 ERROR ("java plugin: cjni_write_one_plugin: "
1484 "Calling `Write' on an `%s' object failed with status %i.",
1485 jp->class_name, status);
1490 } /* }}} int cjni_write_one_plugin */
1492 static int cjni_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */
1493 user_data_t __attribute__((unused)) *user_data)
1502 ERROR ("java plugin: cjni_write: jvm == NULL");
1506 if ((user_data == NULL) || (user_data->data == NULL))
1508 ERROR ("java plugin: cjni_read: Invalid user data.");
1512 jvm_env = cjni_thread_attach ();
1513 if (jvm_env == NULL)
1516 vl_java = ctoj_value_list (jvm_env, ds, vl);
1517 if (vl_java == NULL)
1519 ERROR ("java plugin: cjni_write_plugins: ctoj_value_list failed.");
1523 jp = (java_plugin_t *) user_data->data;
1525 cjni_write_one_plugin (jvm_env, jp, vl_java);
1527 (*jvm_env)->DeleteLocalRef (jvm_env, vl_java);
1529 status = cjni_thread_detach ();
1534 } /* }}} int cjni_write */
1536 static int cjni_shutdown_one_plugin (JNIEnv *jvm_env, /* {{{ */
1542 || ((jp->flags & CJNI_FLAG_ENABLED) == 0)
1543 || (jp->m_shutdown == NULL))
1546 status = (*jvm_env)->CallIntMethod (jvm_env, jp->object_ptr,
1550 ERROR ("cjni_shutdown_one_plugin: Destroying an `%s' object failed "
1551 "with status %i.", jp->class_name, status);
1554 jp->flags &= ~CJNI_FLAG_ENABLED;
1557 } /* }}} int cjni_shutdown_one_plugin */
1559 static int cjni_shutdown_plugins (JNIEnv *jvm_env) /* {{{ */
1563 for (j = 0; j < java_plugins_num; j++)
1564 cjni_shutdown_one_plugin (jvm_env, &java_plugins[j]);
1567 } /* }}} int cjni_shutdown_plugins */
1569 static int cjni_shutdown (void) /* {{{ */
1572 JavaVMAttachArgs args;
1580 memset (&args, 0, sizeof (args));
1581 args.version = JNI_VERSION_1_2;
1583 status = (*jvm)->AttachCurrentThread (jvm, (void **) &jvm_env, &args);
1586 ERROR ("java plugin: cjni_read: AttachCurrentThread failed with status %i.",
1591 cjni_shutdown_plugins (jvm_env);
1593 (*jvm)->DestroyJavaVM (jvm);
1597 pthread_key_delete (jvm_env_key);
1599 for (i = 0; i < jvm_argc; i++)
1601 sfree (jvm_argv[i]);
1606 for (i = 0; i < java_plugins_num; i++)
1608 sfree (java_plugins[i].class_name);
1609 oconfig_free (java_plugins[i].ci);
1611 sfree (java_plugins);
1612 java_plugins_num = 0;
1615 } /* }}} int cjni_shutdown */
1617 static int cjni_read_one_plugin (JNIEnv *jvm_env, java_plugin_t *jp) /* {{{ */
1622 || ((jp->flags & CJNI_FLAG_ENABLED) == 0)
1623 || (jp->m_read == NULL))
1626 DEBUG ("java plugin: Calling: %s.Read()", jp->class_name);
1628 status = (*jvm_env)->CallIntMethod (jvm_env, jp->object_ptr,
1632 ERROR ("java plugin: cjni_read_one_plugin: "
1633 "Calling `Read' on an `%s' object failed with status %i.",
1634 jp->class_name, status);
1639 } /* }}} int cjni_read_one_plugin */
1641 static int cjni_read (user_data_t *user_data) /* {{{ */
1649 ERROR ("java plugin: cjni_read: jvm == NULL");
1653 if ((user_data == NULL) || (user_data->data == NULL))
1655 ERROR ("java plugin: cjni_read: Invalid user data.");
1659 jvm_env = cjni_thread_attach ();
1660 if (jvm_env == NULL)
1663 jp = (java_plugin_t *) user_data->data;
1665 cjni_read_one_plugin (jvm_env, jp);
1667 status = cjni_thread_detach ();
1672 } /* }}} int cjni_read */
1674 static int cjni_init_one_plugin (JNIEnv *jvm_env, java_plugin_t *jp) /* {{{ */
1676 char plugin_name[128];
1677 jmethodID constructor_id;
1680 jp->class_ptr = (*jvm_env)->FindClass (jvm_env, jp->class_name);
1681 if (jp->class_ptr == NULL)
1683 ERROR ("cjni_init_one_plugin: FindClass (%s) failed.",
1688 constructor_id = (*jvm_env)->GetMethodID (jvm_env, jp->class_ptr,
1690 if (constructor_id == NULL)
1692 ERROR ("cjni_init_one_plugin: Could not find the constructor for `%s'.",
1697 jp->object_ptr = (*jvm_env)->NewObject (jvm_env, jp->class_ptr,
1699 if (jp->object_ptr == NULL)
1701 ERROR ("cjni_init_one_plugin: Could create a new `%s' object.",
1706 jp->m_config = (*jvm_env)->GetMethodID (jvm_env, jp->class_ptr,
1707 "Config", "(Lorg/collectd/api/OConfigItem;)I");
1708 DEBUG ("java plugin: cjni_init_one_plugin: "
1709 "jp->class_name = %s; jp->m_config = %p;",
1710 jp->class_name, (void *) jp->m_config);
1712 jp->m_init = (*jvm_env)->GetMethodID (jvm_env, jp->class_ptr,
1714 DEBUG ("java plugin: cjni_init_one_plugin: "
1715 "jp->class_name = %s; jp->m_init = %p;",
1716 jp->class_name, (void *) jp->m_init);
1718 jp->m_read = (*jvm_env)->GetMethodID (jvm_env, jp->class_ptr,
1720 DEBUG ("java plugin: cjni_init_one_plugin: "
1721 "jp->class_name = %s; jp->m_read = %p;",
1722 jp->class_name, (void *) jp->m_read);
1724 jp->m_write = (*jvm_env)->GetMethodID (jvm_env, jp->class_ptr,
1725 "Write", "(Lorg/collectd/api/ValueList;)I");
1726 DEBUG ("java plugin: cjni_init_one_plugin: "
1727 "jp->class_name = %s; jp->m_write = %p;",
1728 jp->class_name, (void *) jp->m_write);
1730 jp->m_shutdown = (*jvm_env)->GetMethodID (jvm_env, jp->class_ptr,
1732 DEBUG ("java plugin: cjni_init_one_plugin: "
1733 "jp->class_name = %s; jp->m_shutdown = %p;",
1734 jp->class_name, (void *) jp->m_shutdown);
1738 if (jp->m_config == NULL)
1740 WARNING ("java plugin: Configuration for the `%s' plugin is present, "
1741 "but plugin doesn't provide a configuration method.",
1744 else /* if (jp->m_config != NULL) */
1748 o_ocitem = ctoj_oconfig_item (jvm_env, jp->ci);
1749 if (o_ocitem == NULL)
1751 ERROR ("java plugin: Creating an OConfigItem object failed. "
1752 "Can't pass configuration information to the `%s' plugin!",
1755 else /* if (o_ocitem != NULL) */
1757 status = (*jvm_env)->CallIntMethod (jvm_env,
1758 jp->object_ptr, jp->m_config, o_ocitem);
1761 ERROR ("java plugin: cjni_init_one_plugin: "
1762 "Configuring the `%s' object failed with status %i.",
1763 jp->class_name, status);
1764 (*jvm_env)->DeleteLocalRef (jvm_env, o_ocitem);
1767 (*jvm_env)->DeleteLocalRef (jvm_env, o_ocitem);
1768 } /* if (o_ocitem != NULL) */
1769 } /* if (jp->m_config != NULL) */
1770 } /* if (jp->ci != NULL) */
1772 if (jp->m_init != NULL)
1774 status = (*jvm_env)->CallIntMethod (jvm_env, jp->object_ptr,
1778 ERROR ("java plugin: cjni_init_one_plugin: "
1779 "Initializing `%s' object failed with status %i.",
1780 jp->class_name, status);
1784 jp->flags |= CJNI_FLAG_ENABLED;
1786 ssnprintf (plugin_name, sizeof (plugin_name), "java:%s", jp->class_name);
1787 if (jp->m_read != NULL)
1791 memset (&ud, 0, sizeof (ud));
1793 ud.free_func = NULL;
1795 plugin_register_complex_read (plugin_name, cjni_read, &ud);
1798 if (jp->m_write != NULL)
1802 memset (&ud, 0, sizeof (ud));
1804 ud.free_func = NULL;
1806 plugin_register_write (plugin_name, cjni_write, &ud);
1810 } /* }}} int cjni_init_one_plugin */
1812 static int cjni_init_plugins (JNIEnv *jvm_env) /* {{{ */
1819 for (j = 0; j < java_plugins_num; j++)
1821 cjni_init_one_plugin (jvm_env, &java_plugins[j]);
1823 if (java_plugins[j].m_shutdown != NULL)
1827 if (have_shutdown > 0)
1828 plugin_register_shutdown ("java", cjni_shutdown);
1831 } /* }}} int cjni_init_plugins */
1833 static int cjni_init_native (JNIEnv *jvm_env) /* {{{ */
1835 jclass api_class_ptr;
1838 api_class_ptr = (*jvm_env)->FindClass (jvm_env, "org.collectd.api.CollectdAPI");
1839 if (api_class_ptr == NULL)
1841 ERROR ("cjni_init_native: Cannot find API class `org.collectd.api.CollectdAPI'.");
1845 status = (*jvm_env)->RegisterNatives (jvm_env, api_class_ptr,
1846 jni_api_functions, (jint) jni_api_functions_num);
1849 ERROR ("cjni_init_native: RegisterNatives failed with status %i.", status);
1854 } /* }}} int cjni_init_native */
1856 static int cjni_init (void) /* {{{ */
1859 JavaVMInitArgs vm_args;
1860 JavaVMOption vm_options[jvm_argc];
1868 status = pthread_key_create (&jvm_env_key, cjni_jvm_env_destroy);
1871 ERROR ("java plugin: cjni_init: pthread_key_create failed "
1872 "with status %i.", status);
1878 memset (&vm_args, 0, sizeof (vm_args));
1879 vm_args.version = JNI_VERSION_1_2;
1880 vm_args.options = vm_options;
1881 vm_args.nOptions = (jint) jvm_argc;
1883 for (i = 0; i < jvm_argc; i++)
1885 DEBUG ("java plugin: cjni_init: jvm_argv[%zu] = %s", i, jvm_argv[i]);
1886 vm_args.options[i].optionString = jvm_argv[i];
1889 vm_args.options[0].optionString = "-verbose:jni";
1890 vm_args.options[1].optionString = "-Djava.class.path=/home/octo/collectd/bindings/java";
1893 status = JNI_CreateJavaVM (&jvm, (void **) &jvm_env, (void **) &vm_args);
1896 ERROR ("cjni_init: JNI_CreateJavaVM failed with status %i.",
1900 assert (jvm != NULL);
1901 assert (jvm_env != NULL);
1903 /* Call RegisterNatives */
1904 status = cjni_init_native (jvm_env);
1907 ERROR ("cjni_init: cjni_init_native failed.");
1911 cjni_init_plugins (jvm_env);
1914 } /* }}} int cjni_init */
1916 void module_register (void)
1918 plugin_register_complex_config ("java", cjni_config);
1919 plugin_register_init ("java", cjni_init);
1920 } /* void module_register (void) */
1922 /* vim: set sw=2 sts=2 et fdm=marker : */