From 0300aefaeb9bac0a771cce6d11fa1f4c637e49d2 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Tue, 24 Feb 2009 10:11:56 +0100 Subject: [PATCH] java plugin: Add support for `target' callbacks. With the ``do everything while in the configuration phase'' issues all sorted out, this was actually kinda easy. Matches and targets share a lot of code, so that the patch actually isn't all that large.. Now, the Java plugin is feature-complete \o/ --- bindings/java/org/collectd/api/Collectd.java | 152 +++++++++++++++++- .../api/CollectdTargetFactoryInterface.java | 49 ++++++ .../org/collectd/api/CollectdTargetInterface.java | 48 ++++++ src/java.c | 172 ++++++++++++++++----- 4 files changed, 382 insertions(+), 39 deletions(-) create mode 100644 bindings/java/org/collectd/api/CollectdTargetFactoryInterface.java create mode 100644 bindings/java/org/collectd/api/CollectdTargetInterface.java diff --git a/bindings/java/org/collectd/api/Collectd.java b/bindings/java/org/collectd/api/Collectd.java index 15e177c6..022fd076 100644 --- a/bindings/java/org/collectd/api/Collectd.java +++ b/bindings/java/org/collectd/api/Collectd.java @@ -24,89 +24,225 @@ package org.collectd.api; /** * Java API to internal functions of collectd. * + * All functions in this class are {@code static}. You don't need to create an + * object of this class (in fact, you can't). Just call these functions + * directly. + * * @author Florian Forster <octo at verplant.org> */ public class Collectd { + + /** + * Constant for severity (log level) "error". + * + * @see CollectdLogInterface + */ public static final int LOG_ERR = 3; + + /** + * Constant for severity (log level) "warning". + * + * @see CollectdLogInterface + */ public static final int LOG_WARNING = 4; + + /** + * Constant for severity (log level) "notice". + * + * @see CollectdLogInterface + */ public static final int LOG_NOTICE = 5; + + /** + * Constant for severity (log level) "info". + * + * @see CollectdLogInterface + */ public static final int LOG_INFO = 6; + + /** + * Constant for severity (log level) "debug". + * + * @see CollectdLogInterface + */ public static final int LOG_DEBUG = 7; + /** + * Return value of match methods: No match. + * + * This is one of two valid return values from match callbacks, indicating + * that the passed {@link DataSet} and {@link ValueList} did not match. + * + * Do not use the numeric value directly, it is subject to change without + * notice! + * + * @see CollectdMatchInterface + */ public static final int FC_MATCH_NO_MATCH = 0; + + /** + * Return value of match methods: Match. + * + * This is one of two valid return values from match callbacks, indicating + * that the passed {@link DataSet} and {@link ValueList} did match. + * + * Do not use the numeric value directly, it is subject to change without + * notice! + * + * @see CollectdMatchInterface + */ public static final int FC_MATCH_MATCHES = 1; + /** + * Return value of target methods: Continue. + * + * This is one of three valid return values from target callbacks, indicating + * that processing of the {@link ValueList} should continue. + * + * Do not use the numeric value directly, it is subject to change without + * notice! + * + * @see CollectdTargetInterface + */ public static final int FC_TARGET_CONTINUE = 0; + + /** + * Return value of target methods: Stop. + * + * This is one of three valid return values from target callbacks, indicating + * that processing of the {@link ValueList} should stop immediately. + * + * Do not use the numeric value directly, it is subject to change without + * notice! + * + * @see CollectdTargetInterface + */ public static final int FC_TARGET_STOP = 1; + + /** + * Return value of target methods: Return. + * + * This is one of three valid return values from target callbacks, indicating + * that processing of the current chain should be stopped and processing of + * the {@link ValueList} should continue in the calling chain. + * + * Do not use the numeric value directly, it is subject to change without + * notice! + * + * @see CollectdTargetInterface + */ public static final int FC_TARGET_RETURN = 2; /** * Java representation of collectd/src/plugin.h:plugin_register_config + * + * @return Zero when successful, non-zero otherwise. + * @see CollectdConfigInterface */ native public static int registerConfig (String name, CollectdConfigInterface object); /** * Java representation of collectd/src/plugin.h:plugin_register_init + * + * @return Zero when successful, non-zero otherwise. + * @see CollectdInitInterface */ native public static int registerInit (String name, CollectdInitInterface object); /** * Java representation of collectd/src/plugin.h:plugin_register_read + * + * @return Zero when successful, non-zero otherwise. + * @see CollectdReadInterface */ native public static int registerRead (String name, CollectdReadInterface object); /** * Java representation of collectd/src/plugin.h:plugin_register_write + * + * @return Zero when successful, non-zero otherwise. + * @see CollectdWriteInterface */ native public static int registerWrite (String name, CollectdWriteInterface object); /** * Java representation of collectd/src/plugin.h:plugin_register_flush + * + * @return Zero when successful, non-zero otherwise. + * @see CollectdFlushInterface */ native public static int registerFlush (String name, CollectdFlushInterface object); /** * Java representation of collectd/src/plugin.h:plugin_register_shutdown + * + * @return Zero when successful, non-zero otherwise. + * @see CollectdShutdownInterface */ native public static int registerShutdown (String name, CollectdShutdownInterface object); /** * Java representation of collectd/src/plugin.h:plugin_register_log + * + * @return Zero when successful, non-zero otherwise. + * @see CollectdLogInterface */ native public static int registerLog (String name, CollectdLogInterface object); /** * Java representation of collectd/src/plugin.h:plugin_register_notification + * + * @return Zero when successful, non-zero otherwise. + * @see CollectdNotificationInterface */ native public static int registerNotification (String name, CollectdNotificationInterface object); /** * Java representation of collectd/src/filter_chain.h:fc_register_match + * + * @return Zero when successful, non-zero otherwise. + * @see CollectdMatchFactoryInterface */ native public static int registerMatch (String name, CollectdMatchFactoryInterface object); /** + * Java representation of collectd/src/filter_chain.h:fc_register_target + * + * @return Zero when successful, non-zero otherwise. + * @see CollectdTargetTargetInterface + */ + native public static int registerTarget (String name, + CollectdTargetFactoryInterface object); + + /** * Java representation of collectd/src/plugin.h:plugin_dispatch_values + * + * @return Zero when successful, non-zero otherwise. */ native public static int dispatchValues (ValueList vl); /** * Java representation of collectd/src/plugin.h:plugin_dispatch_notification + * + * @return Zero when successful, non-zero otherwise. */ native public static int dispatchNotification (Notification n); /** * Java representation of collectd/src/plugin.h:plugin_get_ds + * + * @return The appropriate {@link DataSet} object or {@code null} if no such + * type is registered. */ native public static DataSet getDS (String type); @@ -115,31 +251,45 @@ public class Collectd */ native private static void log (int severity, String message); + /** + * Prints an error message. + */ public static void logError (String message) { log (LOG_ERR, message); } /* void logError */ + /** + * Prints a warning message. + */ public static void logWarning (String message) { log (LOG_WARNING, message); } /* void logWarning */ + /** + * Prints a notice. + */ public static void logNotice (String message) { log (LOG_NOTICE, message); } /* void logNotice */ + /** + * Prints an info message. + */ public static void logInfo (String message) { log (LOG_INFO, message); } /* void logInfo */ + /** + * Prints a debug message. + */ public static void logDebug (String message) { log (LOG_DEBUG, message); } /* void logDebug */ - } /* class Collectd */ /* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/bindings/java/org/collectd/api/CollectdTargetFactoryInterface.java b/bindings/java/org/collectd/api/CollectdTargetFactoryInterface.java new file mode 100644 index 00000000..65f61818 --- /dev/null +++ b/bindings/java/org/collectd/api/CollectdTargetFactoryInterface.java @@ -0,0 +1,49 @@ +/* + * collectd/java - org/collectd/api/CollectdTargetFactoryInterface.java + * Copyright (C) 2009 Florian octo Forster + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; only version 2 of the License is applicable. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: + * Florian octo Forster + */ + +package org.collectd.api; + +/** + * Interface for objects implementing a "target factory". + * + * Objects implementing this interface are used to create objects implementing + * the CollectdTargetInterface interface. + * + * @author Florian Forster <octo at verplant.org> + * @see CollectdTargetInterface + * @see Collectd#registerTarget + */ +public interface CollectdTargetFactoryInterface +{ + /** + * Create a new "target" object. + * + * This method uses the configuration provided as argument to create a + * new object which must implement the {@link CollectdTargetInterface} + * interface. + * + * This function corresponds to the {@code create} member of the + * {@code src/filter_chain.h:target_proc_t} struct. + * + * @return New {@link CollectdTargetInterface} object. + */ + public CollectdTargetInterface createTarget (OConfigItem ci); +} diff --git a/bindings/java/org/collectd/api/CollectdTargetInterface.java b/bindings/java/org/collectd/api/CollectdTargetInterface.java new file mode 100644 index 00000000..74412a32 --- /dev/null +++ b/bindings/java/org/collectd/api/CollectdTargetInterface.java @@ -0,0 +1,48 @@ +/* + * collectd/java - org/collectd/api/CollectdTargetInterface.java + * Copyright (C) 2009 Florian octo Forster + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; only version 2 of the License is applicable. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: + * Florian octo Forster + */ + +package org.collectd.api; + +/** + * Interface for objects implementing a target method. + * + * These objects are instantiated using objects which implement the + * CollectdTargetFactoryInterface interface. They are not instantiated by the + * daemon directly! + * + * @author Florian Forster <octo at verplant.org> + * @see CollectdTargetFactoryInterface + * @see Collectd#registerTarget + */ +public interface CollectdTargetInterface +{ + /** + * Callback method for targets. + * + * This method is called to perform some action on the given ValueList. + * What precisely is done depends entirely on the implementing class. + * + * @return One of: {@link Collectd#FC_TARGET_CONTINUE}, + * {@link Collectd#FC_TARGET_STOP}, {@link Collectd#FC_TARGET_RETURN} + * @see CollectdTargetFactoryInterface + */ + public int invoke (DataSet ds, ValueList vl); +} /* public interface CollectdTargetInterface */ diff --git a/src/java.c b/src/java.c index 2c40cf04..c6d4aeef 100644 --- a/src/java.c +++ b/src/java.c @@ -111,9 +111,11 @@ static int cjni_flush (int timeout, const char *identifier, user_data_t *ud); static void cjni_log (int severity, const char *message, user_data_t *ud); static int cjni_notification (const notification_t *n, user_data_t *ud); -static int cjni_match_create (const oconfig_item_t *ci, void **user_data); -static int cjni_match_destroy (void **user_data); -static int cjni_match_match (const data_set_t *ds, const value_list_t *vl, +/* Create, destroy, and match/invoke functions, used by both, matches AND + * targets. */ +static int cjni_match_target_create (const oconfig_item_t *ci, void **user_data); +static int cjni_match_target_destroy (void **user_data); +static int cjni_match_target_invoke (const data_set_t *ds, value_list_t *vl, notification_meta_t **meta, void **user_data); /* @@ -1512,38 +1514,62 @@ static jint JNICALL cjni_api_register_notification (JNIEnv *jvm_env, /* {{{ */ return (0); } /* }}} jint cjni_api_register_notification */ -static jint JNICALL cjni_api_register_match (JNIEnv *jvm_env, /* {{{ */ - jobject this, jobject o_name, jobject o_match) +static jint JNICALL cjni_api_register_match_target (JNIEnv *jvm_env, /* {{{ */ + jobject this, jobject o_name, jobject o_match, int type) { - match_proc_t proc; int status; const char *c_name; c_name = (*jvm_env)->GetStringUTFChars (jvm_env, o_name, 0); if (c_name == NULL) { - ERROR ("java plugin: cjni_api_register_match: " + ERROR ("java plugin: cjni_api_register_match_target: " "GetStringUTFChars failed."); return (-1); } - status = cjni_callback_register (jvm_env, o_name, o_match, CB_TYPE_MATCH); + status = cjni_callback_register (jvm_env, o_name, o_match, type); if (status != 0) { (*jvm_env)->ReleaseStringUTFChars (jvm_env, o_name, c_name); return (-1); } - memset (&proc, 0, sizeof (proc)); - proc.create = cjni_match_create; - proc.destroy = cjni_match_destroy; - proc.match = cjni_match_match; + if (type == CB_TYPE_MATCH) + { + match_proc_t m_proc; + + memset (&m_proc, 0, sizeof (m_proc)); + m_proc.create = cjni_match_target_create; + m_proc.destroy = cjni_match_target_destroy; + m_proc.match = (void *) cjni_match_target_invoke; + + status = fc_register_match (c_name, m_proc); + } + else if (type == CB_TYPE_TARGET) + { + target_proc_t t_proc; + + memset (&t_proc, 0, sizeof (t_proc)); + t_proc.create = cjni_match_target_create; + t_proc.destroy = cjni_match_target_destroy; + t_proc.invoke = cjni_match_target_invoke; + + status = fc_register_target (c_name, t_proc); + } + else + { + ERROR ("java plugin: cjni_api_register_match_target: " + "Don't know whether to create a match or a target."); + (*jvm_env)->ReleaseStringUTFChars (jvm_env, o_name, c_name); + return (-1); + } - status = fc_register_match (c_name, proc); if (status != 0) { - ERROR ("java plugin: cjni_api_register_match: " - "fc_register_match failed."); + ERROR ("java plugin: cjni_api_register_match_target: " + "%s failed.", + (type == CB_TYPE_MATCH) ? "fc_register_match" : "fc_register_target"); (*jvm_env)->ReleaseStringUTFChars (jvm_env, o_name, c_name); return (-1); } @@ -1551,8 +1577,22 @@ static jint JNICALL cjni_api_register_match (JNIEnv *jvm_env, /* {{{ */ (*jvm_env)->ReleaseStringUTFChars (jvm_env, o_name, c_name); return (0); +} /* }}} jint cjni_api_register_match_target */ + +static jint JNICALL cjni_api_register_match (JNIEnv *jvm_env, /* {{{ */ + jobject this, jobject o_name, jobject o_match) +{ + return (cjni_api_register_match_target (jvm_env, this, o_name, o_match, + CB_TYPE_MATCH)); } /* }}} jint cjni_api_register_match */ +static jint JNICALL cjni_api_register_target (JNIEnv *jvm_env, /* {{{ */ + jobject this, jobject o_name, jobject o_target) +{ + return (cjni_api_register_match_target (jvm_env, this, o_name, o_target, + CB_TYPE_TARGET)); +} /* }}} jint cjni_api_register_target */ + static void JNICALL cjni_api_log (JNIEnv *jvm_env, /* {{{ */ jobject this, jint severity, jobject o_message) { @@ -1627,6 +1667,10 @@ static JNINativeMethod jni_api_functions[] = /* {{{ */ "(Ljava/lang/String;Lorg/collectd/api/CollectdMatchFactoryInterface;)I", cjni_api_register_match }, + { "registerTarget", + "(Ljava/lang/String;Lorg/collectd/api/CollectdTargetFactoryInterface;)I", + cjni_api_register_target }, + { "log", "(ILjava/lang/String;)V", cjni_api_log }, @@ -1696,6 +1740,12 @@ static cjni_callback_info_t *cjni_callback_info_create (JNIEnv *jvm_env, /* {{{ "Lorg/collectd/api/CollectdMatchInterface;"; break; + case CB_TYPE_TARGET: + method_name = "createTarget"; + method_signature = "(Lorg/collectd/api/OConfigItem;)" + "Lorg/collectd/api/CollectdTargetInterface;"; + break; + default: ERROR ("java plugin: cjni_callback_info_create: Unknown type: %#x", type); @@ -1792,6 +1842,10 @@ static int cjni_callback_register (JNIEnv *jvm_env, /* {{{ */ type_str = "match"; break; + case CB_TYPE_TARGET: + type_str = "target"; + break; + default: type_str = ""; } @@ -2552,7 +2606,7 @@ static int cjni_notification (const notification_t *n, /* {{{ */ } /* }}} int cjni_notification */ /* Callbacks for matches implemented in Java */ -static int cjni_match_create (const oconfig_item_t *ci, /* {{{ */ +static int cjni_match_target_create (const oconfig_item_t *ci, /* {{{ */ void **user_data) { JNIEnv *jvm_env; @@ -2560,6 +2614,7 @@ static int cjni_match_create (const oconfig_item_t *ci, /* {{{ */ cjni_callback_info_t *cbi_factory; const char *name; jobject o_ci; + int type; size_t i; cbi_ret = NULL; @@ -2592,6 +2647,18 @@ static int cjni_match_create (const oconfig_item_t *ci, /* {{{ */ BAIL_OUT (-1); } + /* Find out whether to create a match or a target. */ + if (strcasecmp ("Match", ci->key) == 0) + type = CB_TYPE_MATCH; + else if (strcasecmp ("Target", ci->key) == 0) + type = CB_TYPE_TARGET; + else + { + ERROR ("java plugin: cjni_match_target_create: Can't figure out whether " + "to create a match or a target."); + BAIL_OUT (-1); + } + /* This is the name of the match we should create. */ name = ci->values[0].value.string; @@ -2599,7 +2666,7 @@ static int cjni_match_create (const oconfig_item_t *ci, /* {{{ */ cbi_factory = NULL; for (i = 0; i < java_callbacks_num; i++) { - if (java_callbacks[i].type != CB_TYPE_MATCH) + if (java_callbacks[i].type != type) continue; if (strcmp (name, java_callbacks[i].name) != 0) @@ -2612,7 +2679,7 @@ static int cjni_match_create (const oconfig_item_t *ci, /* {{{ */ /* Nope, no factory for that name.. */ if (cbi_factory == NULL) { - ERROR ("java plugin: cjni_match_create: " + ERROR ("java plugin: cjni_match_target_create: " "No such match factory registered: %s", name); BAIL_OUT (-1); @@ -2622,7 +2689,8 @@ static int cjni_match_create (const oconfig_item_t *ci, /* {{{ */ o_ci = ctoj_oconfig_item (jvm_env, ci); if (o_ci == NULL) { - ERROR ("java plugin: cjni_match_create: ctoj_oconfig_item failed."); + ERROR ("java plugin: cjni_match_target_create: " + "ctoj_oconfig_item failed."); BAIL_OUT (-1); } @@ -2631,17 +2699,18 @@ static int cjni_match_create (const oconfig_item_t *ci, /* {{{ */ cbi_ret = (cjni_callback_info_t *) malloc (sizeof (*cbi_ret)); if (cbi_ret == NULL) { - ERROR ("java plugin: cjni_match_create: ctoj_oconfig_item failed."); + ERROR ("java plugin: cjni_match_target_create: malloc failed."); BAIL_OUT (-1); } memset (cbi_ret, 0, sizeof (*cbi_ret)); cbi_ret->object = NULL; + cbi_ret->type = type; /* Lets fill the callback info structure.. First, the name: */ cbi_ret->name = strdup (name); if (cbi_ret->name == NULL) { - ERROR ("java plugin: cjni_match_create: strdup failed."); + ERROR ("java plugin: cjni_match_target_create: strdup failed."); BAIL_OUT (-1); } @@ -2650,7 +2719,7 @@ static int cjni_match_create (const oconfig_item_t *ci, /* {{{ */ cbi_factory->object, cbi_factory->method, o_ci); if (cbi_ret->object == NULL) { - ERROR ("java plugin: cjni_match_create: CallObjectMethod failed."); + ERROR ("java plugin: cjni_match_target_create: CallObjectMethod failed."); BAIL_OUT (-1); } @@ -2659,16 +2728,17 @@ static int cjni_match_create (const oconfig_item_t *ci, /* {{{ */ cbi_ret->class = (*jvm_env)->GetObjectClass (jvm_env, cbi_ret->object); if (cbi_ret->class == NULL) { - ERROR ("java plugin: cjni_match_create: GetObjectClass failed."); + ERROR ("java plugin: cjni_match_target_create: GetObjectClass failed."); BAIL_OUT (-1); } /* Lookup the `int match (DataSet, ValueList)' method. */ cbi_ret->method = (*jvm_env)->GetMethodID (jvm_env, cbi_ret->class, - "match", "(Lorg/collectd/api/DataSet;Lorg/collectd/api/ValueList;)I"); + /* method name = */ (type == CB_TYPE_MATCH) ? "match" : "invoke", + "(Lorg/collectd/api/DataSet;Lorg/collectd/api/ValueList;)I"); if (cbi_ret->method == NULL) { - ERROR ("java plugin: cjni_match_create: GetMethodID failed."); + ERROR ("java plugin: cjni_match_target_create: GetMethodID failed."); BAIL_OUT (-1); } @@ -2681,24 +2751,25 @@ static int cjni_match_create (const oconfig_item_t *ci, /* {{{ */ cjni_thread_detach (); - DEBUG ("java plugin: cjni_match_create: Successfully created a `%s' match.", - cbi_ret->name); + DEBUG ("java plugin: cjni_match_target_create: " + "Successfully created a `%s' %s.", + cbi_ret->name, (type == CB_TYPE_MATCH) ? "match" : "target"); /* Success! */ return (0); #undef BAIL_OUT -} /* }}} int cjni_match_create */ +} /* }}} int cjni_match_target_create */ -static int cjni_match_destroy (void **user_data) /* {{{ */ +static int cjni_match_target_destroy (void **user_data) /* {{{ */ { cjni_callback_info_destroy (*user_data); *user_data = NULL; return (0); -} /* }}} int cjni_match_destroy */ +} /* }}} int cjni_match_target_destroy */ -static int cjni_match_match (const data_set_t *ds, /* {{{ */ - const value_list_t *vl, notification_meta_t **meta, void **user_data) +static int cjni_match_target_invoke (const data_set_t *ds, /* {{{ */ + value_list_t *vl, notification_meta_t **meta, void **user_data) { JNIEnv *jvm_env; cjni_callback_info_t *cbi; @@ -2709,7 +2780,7 @@ static int cjni_match_match (const data_set_t *ds, /* {{{ */ if (jvm == NULL) { - ERROR ("java plugin: cjni_match_match: jvm == NULL"); + ERROR ("java plugin: cjni_match_target_invoke: jvm == NULL"); return (-1); } @@ -2722,7 +2793,7 @@ static int cjni_match_match (const data_set_t *ds, /* {{{ */ o_vl = ctoj_value_list (jvm_env, ds, vl); if (o_vl == NULL) { - ERROR ("java plugin: cjni_match_match: ctoj_value_list failed."); + ERROR ("java plugin: cjni_match_target_invoke: ctoj_value_list failed."); cjni_thread_detach (); return (-1); } @@ -2730,7 +2801,7 @@ static int cjni_match_match (const data_set_t *ds, /* {{{ */ o_ds = ctoj_data_set (jvm_env, ds); if (o_ds == NULL) { - ERROR ("java plugin: cjni_match_match: ctoj_value_list failed."); + ERROR ("java plugin: cjni_match_target_invoke: ctoj_value_list failed."); cjni_thread_detach (); return (-1); } @@ -2738,14 +2809,39 @@ static int cjni_match_match (const data_set_t *ds, /* {{{ */ ret_status = (*jvm_env)->CallIntMethod (jvm_env, cbi->object, cbi->method, o_ds, o_vl); - DEBUG ("java plugin: cjni_match_match: Method returned %i.", ret_status); + DEBUG ("java plugin: cjni_match_target_invoke: Method returned %i.", ret_status); + + /* If we're executing a target, copy the `ValueList' back to our + * `value_list_t'. */ + if (cbi->type == CB_TYPE_TARGET) + { + value_list_t new_vl; + + memset (&new_vl, 0, sizeof (new_vl)); + status = jtoc_value_list (jvm_env, &new_vl, o_vl); + if (status != 0) + { + ERROR ("java plugin: cjni_match_target_invoke: " + "jtoc_value_list failed."); + } + else /* if (status == 0) */ + { + /* plugin_dispatch_values assures that this is dynamically allocated + * memory. */ + sfree (vl->values); + + /* This will replace the vl->values pointer to a new, dynamically + * allocated piece of memory. */ + memcpy (vl, &new_vl, sizeof (*vl)); + } + } /* if (cbi->type == CB_TYPE_TARGET) */ status = cjni_thread_detach (); if (status != 0) ERROR ("java plugin: cjni_read: cjni_thread_detach failed."); return (ret_status); -} /* }}} int cjni_match_match */ +} /* }}} int cjni_match_target_invoke */ /* Iterate over `java_callbacks' and call all CB_TYPE_INIT callbacks. */ static int cjni_init_plugins (JNIEnv *jvm_env) /* {{{ */ @@ -2876,7 +2972,7 @@ static int cjni_init (void) /* {{{ */ if (jvm == NULL) { - ERROR ("java plugin: cjni_match_match: jvm == NULL"); + ERROR ("java plugin: cjni_init: jvm == NULL"); return (-1); } -- 2.11.0