Many build fixes that turned up with GCC 4.6.
[collectd.git] / src / java.c
index 80c17c3..a8ffd8e 100644 (file)
@@ -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 "
@@ -612,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, "<init>", "(Ljava.lang.String;)V");
+      c_dataset, "<init>", "(Ljava/lang/String;)V");
   if (m_constructor == NULL)
   {
     ERROR ("java plugin: ctoj_data_set: Looking up the "
@@ -1417,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);
@@ -1929,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);
   }
 
@@ -2189,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);
@@ -2242,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;
@@ -2297,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);
@@ -2305,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;
@@ -2360,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
@@ -2996,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");
@@ -3014,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) */