/*
 * Copyright (C) 2012, Collabora Ltd.
 *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
 * Copyright (C) 2013, Fluendo S.A.
 *   Author: Andoni Morales <amorales@fluendo.com>
 * Copyright (C) 2014, Sebastian Dröge <sebastian@centricular.com>
 * Copyright (C) 2014, Collabora Ltd.
 *   Author: Matthieu Bouron <matthieu.bouron@collabora.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation
 * version 2.1 of the License.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
 *
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gst/gst.h>
#include <pthread.h>
#include <gmodule.h>

#include "gstjniutils.h"

static GModule *java_module;
static jint (*get_created_java_vms) (JavaVM ** vmBuf, jsize bufLen,
    jsize * nVMs);
static jint (*create_java_vm) (JavaVM ** p_vm, JNIEnv ** p_env, void *vm_args);
static JavaVM *java_vm;
static gboolean initialized = FALSE;
static gboolean started_java_vm = FALSE;
static pthread_key_t current_jni_env;

jclass
gst_amc_jni_get_class (JNIEnv * env, const gchar * name)
{
  jclass tmp, ret = NULL;

  GST_DEBUG ("Retrieving Java class %s", name);

  tmp = (*env)->FindClass (env, name);
  if (!tmp) {
    ret = FALSE;
    (*env)->ExceptionClear (env);
    GST_ERROR ("Failed to get %s class", name);
    goto done;
  }

  ret = (*env)->NewGlobalRef (env, tmp);
  if (!ret) {
    (*env)->ExceptionClear (env);
    GST_ERROR ("Failed to get %s class global reference", name);
  }

done:
  if (tmp)
    (*env)->DeleteLocalRef (env, tmp);
  tmp = NULL;

  return ret;
}

jmethodID
gst_amc_jni_get_method (JNIEnv * env, jclass klass, const gchar * name,
    const gchar * signature)
{
  jmethodID ret;

  ret = (*env)->GetMethodID (env, klass, name, signature);
  if (!ret) {
    (*env)->ExceptionClear (env);
    GST_ERROR ("Failed to get method ID %s", name);
  }
  return ret;
}

jmethodID
gst_amc_jni_get_static_method (JNIEnv * env, jclass klass, const gchar * name,
    const gchar * signature)
{
  jmethodID ret;

  ret = (*env)->GetStaticMethodID (env, klass, name, signature);
  if (!ret) {
    (*env)->ExceptionClear (env);
    GST_ERROR ("Failed to get static method id %s", name);
  }
  return ret;
}

jfieldID
gst_amc_jni_get_field_id (JNIEnv * env, jclass klass, const gchar * name,
    const gchar * type)
{
  jfieldID ret;

  ret = (*env)->GetFieldID (env, klass, name, type);
  if (!ret) {
    (*env)->ExceptionClear (env);
    GST_ERROR ("Failed to get field ID %s", name);
  }
  return ret;
}

jobject
gst_amc_jni_new_object (JNIEnv * env, jclass klass, jmethodID constructor, ...)
{
  jobject tmp;
  va_list args;

  va_start (args, constructor);
  tmp = (*env)->NewObjectV (env, klass, constructor, args);
  va_end (args);

  if (!tmp) {
    (*env)->ExceptionClear (env);
    GST_ERROR ("Failed to create object");
    return NULL;
  }

  return gst_amc_jni_object_make_global (env, tmp);
}

jobject
gst_amc_jni_new_object_from_static (JNIEnv * env, jclass klass,
    jmethodID method, ...)
{
  jobject tmp;
  va_list args;

  va_start (args, method);
  tmp = (*env)->CallStaticObjectMethodV (env, klass, method, args);
  va_end (args);

  if ((*env)->ExceptionCheck (env) || !tmp) {
    (*env)->ExceptionClear (env);
    GST_ERROR ("Failed to create object from static method");
    return NULL;
  }

  return gst_amc_jni_object_make_global (env, tmp);
}

jobject
gst_amc_jni_object_make_global (JNIEnv * env, jobject object)
{
  jobject ret;

  ret = (*env)->NewGlobalRef (env, object);
  if (!ret) {
    GST_ERROR ("Failed to create global reference");
    (*env)->ExceptionClear (env);
  } else {
    gst_amc_jni_object_local_unref (env, object);
  }
  return ret;
}

jobject
gst_amc_jni_object_ref (JNIEnv * env, jobject object)
{
  jobject ret;

  ret = (*env)->NewGlobalRef (env, object);
  if (!ret) {
    GST_ERROR ("Failed to create global reference");
    (*env)->ExceptionClear (env);
  }
  return ret;
}

void
gst_amc_jni_object_unref (JNIEnv * env, jobject object)
{
  (*env)->DeleteGlobalRef (env, object);
}

void
gst_amc_jni_object_local_unref (JNIEnv * env, jobject object)
{
  (*env)->DeleteLocalRef (env, object);
}

jstring
gst_amc_jni_string_from_gchar (JNIEnv * env, const gchar * string)
{
  return (*env)->NewStringUTF (env, string);
}

gchar *
gst_amc_jni_string_to_gchar (JNIEnv * env, jstring string, gboolean release)
{
  const gchar *s = NULL;
  gchar *ret = NULL;

  s = (*env)->GetStringUTFChars (env, string, NULL);
  if (!s) {
    GST_ERROR ("Failed to convert string to UTF8");
    (*env)->ExceptionClear (env);
    return ret;
  }

  ret = g_strdup (s);
  (*env)->ReleaseStringUTFChars (env, string, s);

  if (release) {
    (*env)->DeleteLocalRef (env, string);
  }
  return ret;
}

/* getExceptionSummary() and getStackTrace() taken from Android's
 *   platform/libnativehelper/JNIHelp.cpp
 * Modified to work with normal C strings and without C++.
 *
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Returns a human-readable summary of an exception object. The buffer will
 * be populated with the "binary" class name and, if present, the
 * exception message.
 */
static gchar *
getExceptionSummary (JNIEnv * env, jthrowable exception)
{
  GString *gs = g_string_new ("");
  jclass exceptionClass = NULL, classClass = NULL;
  jmethodID classGetNameMethod, getMessage;
  jstring classNameStr = NULL, messageStr = NULL;
  const char *classNameChars, *messageChars;

  /* get the name of the exception's class */
  exceptionClass = (*env)->GetObjectClass (env, exception);
  classClass = (*env)->GetObjectClass (env, exceptionClass);
  classGetNameMethod =
      (*env)->GetMethodID (env, classClass, "getName", "()Ljava/lang/String;");

  classNameStr =
      (jstring) (*env)->CallObjectMethod (env, exceptionClass,
      classGetNameMethod);

  if (classNameStr == NULL) {
    if ((*env)->ExceptionCheck (env))
      (*env)->ExceptionClear (env);
    g_string_append (gs, "<error getting class name>");
    goto done;
  }

  classNameChars = (*env)->GetStringUTFChars (env, classNameStr, NULL);
  if (classNameChars == NULL) {
    if ((*env)->ExceptionCheck (env))
      (*env)->ExceptionClear (env);
    g_string_append (gs, "<error getting class name UTF-8>");
    goto done;
  }

  g_string_append (gs, classNameChars);

  (*env)->ReleaseStringUTFChars (env, classNameStr, classNameChars);

  /* if the exception has a detail message, get that */
  getMessage =
      (*env)->GetMethodID (env, exceptionClass, "getMessage",
      "()Ljava/lang/String;");
  messageStr = (jstring) (*env)->CallObjectMethod (env, exception, getMessage);
  if (messageStr == NULL) {
    if ((*env)->ExceptionCheck (env))
      (*env)->ExceptionClear (env);
    goto done;
  }
  g_string_append (gs, ": ");

  messageChars = (*env)->GetStringUTFChars (env, messageStr, NULL);
  if (messageChars != NULL) {
    g_string_append (gs, messageChars);
    (*env)->ReleaseStringUTFChars (env, messageStr, messageChars);
  } else {
    if ((*env)->ExceptionCheck (env))
      (*env)->ExceptionClear (env);
    g_string_append (gs, "<error getting message>");
  }

done:
  if (exceptionClass)
    (*env)->DeleteLocalRef (env, exceptionClass);
  if (classClass)
    (*env)->DeleteLocalRef (env, classClass);
  if (classNameStr)
    (*env)->DeleteLocalRef (env, classNameStr);
  if (messageStr)
    (*env)->DeleteLocalRef (env, messageStr);

  return g_string_free (gs, FALSE);
}

/*
 * Returns an exception (with stack trace) as a string.
 */
static gchar *
getStackTrace (JNIEnv * env, jthrowable exception)
{
  GString *gs = g_string_new ("");
  jclass stringWriterClass = NULL, printWriterClass = NULL;
  jclass exceptionClass = NULL;
  jmethodID stringWriterCtor, stringWriterToStringMethod;
  jmethodID printWriterCtor, printStackTraceMethod;
  jobject stringWriter = NULL, printWriter = NULL;
  jstring messageStr = NULL;
  const char *utfChars;

  stringWriterClass = (*env)->FindClass (env, "java/io/StringWriter");

  if (stringWriterClass == NULL) {
    g_string_append (gs, "<error getting java.io.StringWriter class>");
    goto done;
  }

  stringWriterCtor =
      (*env)->GetMethodID (env, stringWriterClass, "<init>", "()V");
  stringWriterToStringMethod =
      (*env)->GetMethodID (env, stringWriterClass, "toString",
      "()Ljava/lang/String;");

  printWriterClass = (*env)->FindClass (env, "java/io/PrintWriter");
  if (printWriterClass == NULL) {
    g_string_append (gs, "<error getting java.io.PrintWriter class>");
    goto done;
  }

  printWriterCtor =
      (*env)->GetMethodID (env, printWriterClass, "<init>",
      "(Ljava/io/Writer;)V");
  stringWriter = (*env)->NewObject (env, stringWriterClass, stringWriterCtor);
  if (stringWriter == NULL) {
    if ((*env)->ExceptionCheck (env))
      (*env)->ExceptionClear (env);
    g_string_append (gs, "<error creating new StringWriter instance>");
    goto done;
  }

  printWriter =
      (*env)->NewObject (env, printWriterClass, printWriterCtor, stringWriter);
  if (printWriter == NULL) {
    if ((*env)->ExceptionCheck (env))
      (*env)->ExceptionClear (env);
    g_string_append (gs, "<error creating new PrintWriter instance>");
    goto done;
  }

  exceptionClass = (*env)->GetObjectClass (env, exception);
  printStackTraceMethod =
      (*env)->GetMethodID (env, exceptionClass, "printStackTrace",
      "(Ljava/io/PrintWriter;)V");
  (*env)->CallVoidMethod (env, exception, printStackTraceMethod, printWriter);
  if ((*env)->ExceptionCheck (env)) {
    (*env)->ExceptionClear (env);
    g_string_append (gs, "<exception while printing stack trace>");
    goto done;
  }

  messageStr = (jstring) (*env)->CallObjectMethod (env, stringWriter,
      stringWriterToStringMethod);
  if (messageStr == NULL) {
    if ((*env)->ExceptionCheck (env))
      (*env)->ExceptionClear (env);
    g_string_append (gs, "<failed to call StringWriter.toString()>");
    goto done;
  }

  utfChars = (*env)->GetStringUTFChars (env, messageStr, NULL);
  if (utfChars == NULL) {
    if ((*env)->ExceptionCheck (env))
      (*env)->ExceptionClear (env);
    g_string_append (gs, "<failed to get UTF chars for message>");
    goto done;
  }

  g_string_append (gs, utfChars);

  (*env)->ReleaseStringUTFChars (env, messageStr, utfChars);

done:
  if (stringWriterClass)
    (*env)->DeleteLocalRef (env, stringWriterClass);
  if (printWriterClass)
    (*env)->DeleteLocalRef (env, printWriterClass);
  if (exceptionClass)
    (*env)->DeleteLocalRef (env, exceptionClass);
  if (stringWriter)
    (*env)->DeleteLocalRef (env, stringWriter);
  if (printWriter)
    (*env)->DeleteLocalRef (env, printWriter);
  if (messageStr)
    (*env)->DeleteLocalRef (env, messageStr);

  return g_string_free (gs, FALSE);
}

static JNIEnv *
gst_amc_jni_attach_current_thread (void)
{
  JNIEnv *env;
  JavaVMAttachArgs args;

  GST_DEBUG ("Attaching thread %p", g_thread_self ());
  args.version = JNI_VERSION_1_6;
  args.name = NULL;
  args.group = NULL;

  if ((*java_vm)->AttachCurrentThread (java_vm, &env, &args) < 0) {
    GST_ERROR ("Failed to attach current thread");
    return NULL;
  }

  return env;
}

static void
gst_amc_jni_detach_current_thread (void *env)
{
  GST_DEBUG ("Detaching thread %p", g_thread_self ());
  (*java_vm)->DetachCurrentThread (java_vm);
}

static gboolean
check_nativehelper (void)
{
  GModule *module;
  void **jni_invocation = NULL;
  gboolean ret = FALSE;

  module = g_module_open (NULL, G_MODULE_BIND_LOCAL);
  if (!module)
    return ret;

  /* Check if libnativehelper is loaded in the process and if
   * it has these awful wrappers for JNI_CreateJavaVM and
   * JNI_GetCreatedJavaVMs that crash the app if you don't
   * create a JniInvocation instance first. If it isn't we
   * just fail here and don't initialize anything.
   * See this code for reference:
   * https://android.googlesource.com/platform/libnativehelper/+/master/JniInvocation.cpp
   */
  if (!g_module_symbol (module, "_ZN13JniInvocation15jni_invocation_E",
          (gpointer *) & jni_invocation)) {
    ret = TRUE;
  } else {
    ret = (jni_invocation != NULL && *jni_invocation != NULL);
  }

  g_module_close (module);

  return ret;
}

static gboolean
load_java_module (const gchar * name)
{
  java_module = g_module_open (name, G_MODULE_BIND_LOCAL);
  if (!java_module)
    goto load_failed;

  if (!g_module_symbol (java_module, "JNI_CreateJavaVM",
          (gpointer *) & create_java_vm))
    goto symbol_error;

  if (!g_module_symbol (java_module, "JNI_GetCreatedJavaVMs",
          (gpointer *) & get_created_java_vms))
    goto symbol_error;

  return TRUE;

load_failed:
  {
    GST_ERROR ("Failed to load Java module '%s': %s", GST_STR_NULL (name),
        g_module_error ());
    return FALSE;
  }
symbol_error:
  {
    GST_ERROR ("Failed to locate required JNI symbols in '%s': %s",
        GST_STR_NULL (name), g_module_error ());
    g_module_close (java_module);
    java_module = NULL;
    return FALSE;
  }
}

static gboolean
gst_amc_jni_initialize_java_vm (void)
{
  jsize n_vms;

  /* Returns TRUE if we can safely
   * a) get the current VMs and
   * b) start a VM if none is started yet
   *
   * FIXME: On Android >= 4.4 we won't be able to safely start a
   * VM on our own without using private C++ API!
   */
  if (!check_nativehelper ()) {
    GST_ERROR ("Can't safely check for VMs or start a VM");
    return FALSE;
  }

  if (!load_java_module (NULL)) {
    if (!load_java_module ("libdvm"))
      return FALSE;
  }

  n_vms = 0;
  if (get_created_java_vms (&java_vm, 1, &n_vms) < 0)
    goto get_created_failed;

  if (n_vms > 0) {
    GST_DEBUG ("Successfully got existing Java VM %p", java_vm);
  } else {
    JNIEnv *env;
    JavaVMInitArgs vm_args;
    JavaVMOption options[4];

    GST_DEBUG ("Found no existing Java VM, trying to start one");

    options[0].optionString = "-verbose:jni";
    options[1].optionString = "-verbose:gc";
    options[2].optionString = "-Xcheck:jni";
    options[3].optionString = "-Xdebug";

    vm_args.version = JNI_VERSION_1_4;
    vm_args.options = options;
    vm_args.nOptions = 4;
    vm_args.ignoreUnrecognized = JNI_TRUE;
    if (create_java_vm (&java_vm, &env, &vm_args) < 0)
      goto create_failed;
    GST_DEBUG ("Successfully created Java VM %p", java_vm);

    started_java_vm = TRUE;
  }

  return java_vm != NULL;

get_created_failed:
  {
    GST_ERROR ("Failed to get already created VMs");
    g_module_close (java_module);
    java_module = NULL;
    return FALSE;
  }
create_failed:
  {
    GST_ERROR ("Failed to create a Java VM");
    g_module_close (java_module);
    java_module = NULL;
    return FALSE;
  }
}

static void
gst_amc_jni_set_error_string (JNIEnv * env, GQuark domain, gint code,
    GError ** err, const gchar * message)
{
  jthrowable exception;

  if (!err) {
    if ((*env)->ExceptionCheck (env))
      (*env)->ExceptionClear (env);
    return;
  }

  if ((*env)->ExceptionCheck (env)) {
    if ((exception = (*env)->ExceptionOccurred (env))) {
      gchar *exception_description, *exception_stacktrace;

      /* Clear exception so that we can call Java methods again */
      (*env)->ExceptionClear (env);

      exception_description = getExceptionSummary (env, exception);
      exception_stacktrace = getStackTrace (env, exception);
      g_set_error (err, domain, code, "%s: %s\n%s", message,
          exception_description, exception_stacktrace);
      g_free (exception_description);
      g_free (exception_stacktrace);

      (*env)->DeleteLocalRef (env, exception);
    } else {
      (*env)->ExceptionClear (env);
      g_set_error (err, domain, code, "%s", message);
    }
  } else {
    g_set_error (err, domain, code, "%s", message);
  }
}

G_GNUC_PRINTF (5, 6)
     void gst_amc_jni_set_error (JNIEnv * env, GQuark domain, gint code,
    GError ** err, const gchar * format, ...)
{
  gchar *message;
  va_list var_args;

  va_start (var_args, format);
  message = g_strdup_vprintf (format, var_args);
  va_end (var_args);

  gst_amc_jni_set_error_string (env, domain, code, err, message);

  g_free (message);
}


gboolean
gst_amc_jni_initialize (void)
{
  if (!initialized) {
    pthread_key_create (&current_jni_env, gst_amc_jni_detach_current_thread);
    initialized = gst_amc_jni_initialize_java_vm ();
  }
  return initialized;
}

JNIEnv *
gst_amc_jni_get_env (void)
{
  JNIEnv *env;

  if ((env = pthread_getspecific (current_jni_env)) == NULL) {
    env = gst_amc_jni_attach_current_thread ();
    pthread_setspecific (current_jni_env, env);
  }

  return env;
}

gboolean
gst_amc_jni_is_vm_started (void)
{
  return started_java_vm;
}

#define CALL_STATIC_TYPE_METHOD(_type, _name,  _jname, _retval)                                                     \
_type gst_amc_jni_call_static_##_name##_method (JNIEnv *env, GError ** err, jclass klass, jmethodID methodID, ...)   \
  {                                                                                                          \
    _type ret;                                                                                               \
    va_list args;                                                                                            \
    va_start(args, methodID);                                                                                \
    ret = (*env)->CallStatic##_jname##MethodV(env, klass, methodID, args);                                           \
    if ((*env)->ExceptionCheck (env)) {                                                                      \
      gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,                               \
          err, "Failed to call static Java method");                                                                \
      (*env)->ExceptionClear (env);                                                                          \
      ret = _retval;                                                                                         \
    }                                                                                                        \
    va_end(args);                                                                                            \
    return (_type) ret;                                                                                      \
  }

CALL_STATIC_TYPE_METHOD (gboolean, boolean, Boolean, FALSE);
CALL_STATIC_TYPE_METHOD (gint8, byte, Byte, G_MININT8);
CALL_STATIC_TYPE_METHOD (gshort, short, Short, G_MINSHORT);
CALL_STATIC_TYPE_METHOD (gint, int, Int, G_MININT);
CALL_STATIC_TYPE_METHOD (gchar, char, Char, 0);
CALL_STATIC_TYPE_METHOD (glong, long, Long, G_MINLONG);
CALL_STATIC_TYPE_METHOD (gfloat, float, Float, G_MINFLOAT);
CALL_STATIC_TYPE_METHOD (gdouble, double, Double, G_MINDOUBLE);
CALL_STATIC_TYPE_METHOD (jobject, object, Object, NULL);

gboolean
gst_amc_jni_call_static_void_method (JNIEnv * env, GError ** err, jclass klass,
    jmethodID methodID, ...)
{
  gboolean ret = TRUE;
  va_list args;
  va_start (args, methodID);

  (*env)->CallStaticVoidMethodV (env, klass, methodID, args);
  if ((*env)->ExceptionCheck (env)) {
    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
        err, "Failed to call static Java method");
    (*env)->ExceptionClear (env);
    ret = FALSE;
  }
  va_end (args);
  return ret;
}

#define CALL_TYPE_METHOD(_type, _name,  _jname, _retval)                                                     \
_type gst_amc_jni_call_##_name##_method (JNIEnv *env, GError ** err, jobject obj, jmethodID methodID, ...)   \
  {                                                                                                          \
    _type ret;                                                                                               \
    va_list args;                                                                                            \
    va_start(args, methodID);                                                                                \
    ret = (*env)->Call##_jname##MethodV(env, obj, methodID, args);                                           \
    if ((*env)->ExceptionCheck (env)) {                                                                      \
      gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,                               \
          err, "Failed to call Java method");                                                                \
      (*env)->ExceptionClear (env);                                                                          \
      ret = _retval;                                                                                         \
    }                                                                                                        \
    va_end(args);                                                                                            \
    return (_type) ret;                                                                                      \
  }

CALL_TYPE_METHOD (gboolean, boolean, Boolean, FALSE);
CALL_TYPE_METHOD (gint8, byte, Byte, G_MININT8);
CALL_TYPE_METHOD (gshort, short, Short, G_MINSHORT);
CALL_TYPE_METHOD (gint, int, Int, G_MININT);
CALL_TYPE_METHOD (gchar, char, Char, 0);
CALL_TYPE_METHOD (glong, long, Long, G_MINLONG);
CALL_TYPE_METHOD (gfloat, float, Float, G_MINFLOAT);
CALL_TYPE_METHOD (gdouble, double, Double, G_MINDOUBLE);
CALL_TYPE_METHOD (jobject, object, Object, NULL);

gboolean
gst_amc_jni_call_void_method (JNIEnv * env, GError ** err, jobject obj,
    jmethodID methodID, ...)
{
  gboolean ret = TRUE;
  va_list args;
  va_start (args, methodID);

  (*env)->CallVoidMethodV (env, obj, methodID, args);
  if ((*env)->ExceptionCheck (env)) {
    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
        err, "Failed to call Java method");
    (*env)->ExceptionClear (env);
    ret = FALSE;
  }
  va_end (args);
  return ret;
}

#define GET_TYPE_FIELD(_type, _name, _jname, _retval)                                               \
_type gst_amc_jni_get_##_name##_field (JNIEnv *env, GError ** err, jobject obj, jfieldID fieldID)   \
  {                                                                                                 \
    _type res;                                                                                      \
                                                                                                    \
    res = (*env)->Get##_jname##Field(env, obj, fieldID);                                            \
    if ((*env)->ExceptionCheck (env)) {                                                             \
      gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,                      \
          err, "Failed to call Java field");                                                        \
      (*env)->ExceptionClear (env);                                                                 \
      res = _retval;                                                                                \
    }                                                                                               \
    return res;                                                                                     \
  }

GET_TYPE_FIELD (gint, int, Int, G_MININT);
GET_TYPE_FIELD (glong, long, Long, G_MINLONG);
