diff --git a/ChangeLog b/ChangeLog index 08b159cb2..364d05c2f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2024-07-12 Vedant Tewari + * ax_prog_java.m4: Added macro for jni check + * ax_jni_include_dir.m4: Added macro for jni check + * configure.ac: added support for Java interoperability through JNI 2023-02-25 Ron Norman diff --git a/NEWS b/NEWS index 8d2beb73f..791e52c37 100644 --- a/NEWS +++ b/NEWS @@ -20,7 +20,7 @@ NEWS - user visible changes -*- outline -*- * New GnuCOBOL features - +** Initial support for Java interoperability through JNI (new optional dependency JDK) ** file handling: added backends for ODBC (so far PostgrSQL, MySQL, SQLite, MSSQL) and OCI, along with new directory COB_SCHEMA_DIR containing the necessary internal schema files to match the file definition to the diff --git a/cobc/codegen.c b/cobc/codegen.c index 50da4029f..f72c52b75 100644 --- a/cobc/codegen.c +++ b/cobc/codegen.c @@ -152,7 +152,7 @@ static struct literal_list *literal_cache = NULL; static struct field_list *field_cache = NULL; static struct field_list *local_field_cache = NULL; static struct call_list *call_cache = NULL; -static struct java_call_list *call_java_cache = NULL; +static struct java_call_list *call_java_cache = NULL; static struct call_list *func_call_cache = NULL; static struct static_call_list *static_call_cache = NULL; static struct base_list *base_cache = NULL; @@ -395,15 +395,16 @@ lookup_source (const char *p) } static void -lookup_java_call(const char *p) { +lookup_java_call(const char *p) +{ struct java_call_list *clp; for (clp = call_java_cache; clp; clp = clp->next) { - if (strcmp(p, clp->call_name) == 0) { + if (strcmp (p, clp->call_name) == 0) { return; } } - clp = cobc_parse_malloc(sizeof(struct java_call_list)); + clp = cobc_parse_malloc (sizeof(struct java_call_list)); clp->call_name = p; clp->next = call_java_cache; call_java_cache = clp; @@ -413,6 +414,7 @@ static void lookup_call (const char *p) { struct call_list *clp; + for (clp = call_cache; clp; clp = clp->next) { if (strcmp (p, clp->call_name) == 0) { return; @@ -429,17 +431,18 @@ lookup_func_call (const char *p) { struct call_list *clp; - for (clp = func_call_cache; clp; clp = clp->next) { - if (strcmp (p, clp->call_name) == 0) { - return; - } - } - clp = cobc_parse_malloc (sizeof (struct call_list)); - clp->call_name = p; - clp->next = func_call_cache; - func_call_cache = clp; + for (clp = func_call_cache; clp; clp = clp->next) { + if (strcmp(p, clp->call_name) == 0) { + return; + } + } + clp = cobc_parse_malloc(sizeof(struct call_list)); + clp->call_name = p; + clp->next = func_call_cache; + func_call_cache = clp; } + static void lookup_static_call (const char *p, int convention, int return_type) { @@ -7063,6 +7066,29 @@ output_field_constant (cb_tree x, int n, const char *flagname) output_newline (); } +static void output_java_call(const char *p) +{ + char *first_dot; + char *method_name; + const char *class_name; + + lookup_java_call(p + 6); + output_line("if (call_java_%s == NULL)", p); + output_block_open(); + output_prefix(); + output("call_java_%s = ", p); + first_dot = strchr(p + 6, '.'); + if (first_dot != NULL) { + *first_dot = '\0'; + method_name = first_dot + 1; + class_name = p; + output("cob_resolve_java(\"%s\", \"%s\", \"()V\");", class_name, method_name); + } + output("cob_call_java(call_java_%s);\n", p); + output_newline(); + output_block_close(); +} + static void output_call (struct cb_call *p) { @@ -7553,30 +7579,7 @@ output_call (struct cb_call *p) if (name_is_literal_or_prototype) { s = get_program_id_str (p->name); name_str = cb_encode_program_id (s, 1, cb_fold_call); - if( -#ifdef HAVE_JNI - strncmp("Java.", s, 6) == 0 -#else - 0 -#endif - ) { - lookup_java_call(s + 6); - output_line ("if (call_java_%s == NULL || cob_glob_ptr->cob_physical_cancel)", name_str); - output_block_open(); - output_prefix(); - output ("call_java_%s = ", name_str); - char *first_dot = strchr(s + 6, '.'); - if (first_dot != NULL) { - *first_dot = '\0'; - char *method_name = first_dot + 1; - char *class_name = s; - output("cob_resolve_java (\"%s\", \"%s\", \"()V\");", class_name, method_name); - } - output("cob_call_java(call_java_%s);\n", name_str); - output_newline (); - output_block_close (); - } else { - /* rest */ + output_java_call(s); lookup_call (name_str); callname = s; @@ -7598,7 +7601,6 @@ output_call (struct cb_call *p) } output_newline (); output_block_close (); - } } else { name_str = NULL; needs_unifunc = 1; diff --git a/configure.ac b/configure.ac index 6468b24d1..065ab80e0 100644 --- a/configure.ac +++ b/configure.ac @@ -485,46 +485,6 @@ AC_CHECK_HEADERS([sys/types.h signal.h stddef.h], [], # optional: AC_CHECK_HEADERS([sys/time.h locale.h fcntl.h dlfcn.h sys/wait.h sys/sysmacros.h]) -# Check for JNI -AC_ARG_ENABLE([java], - [AC_HELP_STRING([--disable-java], - [disable Java Interoperability])]) -AS_IF([test X$enable_java != Xno], [ - AX_JNI_INCLUDE_DIR - AS_IF([test "$JNI_INCLUDE_DIRS" = ""], [ - AC_MSG_WARN([JNI include directory not found, disabling Java interoperability]) - ], [ - for JNI_INCLUDE_DIR in $JNI_INCLUDE_DIRS - do - CPPFLAGS="$CPPFLAGS -I$JNI_INCLUDE_DIR" - done - AC_DEFINE([WITH_JNI], [1]) - cob_have_jni=yes - ]) -]) - -#AC_ARG_VAR([JAVA_HOME], [Java Runtime Environment (JRE) location]) -#AS_IF([test X$enable_java != Xno], [ -# AS_IF([test -n "$JAVA_HOME"], -# [CPPFLAGS="$CPPFLAGS -I$JAVA_HOME/include"]) -# AC_CHECK_HEADERS([jni.h], [have_jni=yes], [have_jni=no]) -# dnl case "$target_cpu" in -# dnl x86_64) JVM_ARCH=amd64 ;; -# dnl i?86) JVM_ARCH=i386 ;; -# dnl *) JVM_ARCH=$target_cpu ;; -# dnl esac -# dnl AC_SUBST([JVM_ARCH]) -# dnl AS_IF([test -z "$JAVA_HOME"], -# dnl [LDFLAGS="-L$JAVA_HOME/lib/$JVM_ARCH/client -L$JAVA_HOME/lib/$JVM_ARCH/server $LDFLAGS"] -# AS_IF([test -n "$JNI_INCLUDE_DIRS"], [ -# ]) -# AC_CHECK_LIB([jvm], [JNI_CreateJavaVM], [LIBS=$LIBS], -# [AC_MSG_WARN([no libjvm found; please set JAVA_HOME appropriately])]) -#]) -# AS_IF([test X$enable_java != Xno && test X$have_jni = Xno], [ -# AC_MSG_WARN([JNI support not found; disabling Java Interoperability]) -# ]) - # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_C_BIGENDIAN @@ -974,7 +934,23 @@ AS_IF([test "$with_xml2" = "yes" -o "$with_xml2" = "check"], [ LIBS="$curr_libs"; CPPFLAGS="$curr_cppflags" ]) - +# Check for JNI +AC_ARG_WITH([java], + [AS_HELP_STRING([--without-java], + [disable Java Interoperability])]) +AS_IF([test X$with_java != Xno], [ + AX_JNI_INCLUDE_DIR + AS_IF([test "$JNI_INCLUDE_DIRS" = ""], [ + AC_MSG_WARN([JNI include directory not found, disabling Java interoperability]) + ], [ + for JNI_INCLUDE_DIR in $JNI_INCLUDE_DIRS + do + CPPFLAGS="$CPPFLAGS -I$JNI_INCLUDE_DIR" + done + AC_DEFINE([WITH_JNI], [1]) + cob_have_jni=yes + ]) +]) # Checks for cjson/json-c. AC_MSG_NOTICE([Checks for JSON handler]) diff --git a/libcob/common.h b/libcob/common.h index 6e3c96c3e..e8347f20e 100644 --- a/libcob/common.h +++ b/libcob/common.h @@ -1294,15 +1294,12 @@ struct cob_call_struct { cob_call_union cob_cstr_cancel; /* Cancel entry */ }; -// #ifdef HAVE_JNI -// #include "jni.h" typedef struct __cob_java_static_method cob_java_handle; COB_EXPIMP cob_java_handle* cob_resolve_java (const char *class_name, const char* method_name, const char *type_signature); COB_EXPIMP void cob_call_java (const cob_java_handle *method_handle); -// #endif /* Screen structure */ typedef struct __cob_screen {