-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initial JNI configuration #157
base: java-interop
Are you sure you want to change the base?
Changes from 6 commits
7dbe688
8ac6f69
70f22e1
b7b8b42
1493f2f
0c1eb53
ea840e3
3cfe83d
bb76d66
c1944d1
85be0ef
694669b
86b62c3
708c0e4
9e9c908
8b142f5
56aac26
35e8c3b
caf9f31
78262a1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,11 @@ | ||
|
||
2024-07-12 Vedant Tewari <[email protected]> | ||
|
||
2023-02-25 Ron Norman <[email protected]> | ||
* 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 <[email protected]> | ||
|
||
* configure.ac: Add check for sys/time.h | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -119,3 +119,13 @@ Support for GENERATE JSON is provided by *one* of the following: | |
|
||
JSON-C is distributed under Expat License. | ||
|
||
JNI Support | ||
------------ | ||
|
||
Support for JNI (Java Native Interface) is provided by: | ||
|
||
* [Java Development Kit (JDK)](https://openjdk.java.net/) 8 or later. | ||
|
||
The JDK is distributed under various open-source licenses depending on the vendor and version. Common licenses include the GNU General Public License (GPL) and the Oracle Binary Code License Agreement. | ||
|
||
To enable JNI support, ensure that the JDK is installed on your system, and set the appropriate environment variables (e.g., JAVA_HOME) to point to the JDK installation directory. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please word-wrap as for SCREEN SECTION |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,7 +20,7 @@ NEWS - user visible changes -*- outline -*- | |
|
||
|
||
* New GnuCOBOL features | ||
|
||
** Initial support for Java interoperability through JNI (new optional dependency JDK) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please adjust as for "JSON GENERATE" (just check in the same file searching for "json"):
|
||
** 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 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,8 @@ | ||
|
||
2024-08-14 Nicolas Berthier <[email protected]> | ||
|
||
* cobc.c (cobc_print_info): added note for Java interoperability | ||
|
||
2024-08-04 David Declerck <[email protected]> | ||
|
||
Adjustments to merge 2022-12-21: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This file and most others in cobc miss a ChangeLog entry |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
/* | ||
Copyright (C) 2003-2024 Free Software Foundation, Inc. | ||
Written by Keisuke Nishida, Roger While, Ron Norman, Simon Sobisch, | ||
Edward Hart | ||
Edward Hart, Vedant Tewari | ||
|
||
This file is part of GnuCOBOL. | ||
|
||
|
@@ -147,6 +147,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 call_list *call_java_cache = NULL; | ||
nberth marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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,6 +396,22 @@ lookup_source (const char *p) | |
return source_id++; | ||
} | ||
|
||
static void | ||
lookup_java_call(const char *p) | ||
{ | ||
struct call_list *clp; | ||
|
||
for (clp = call_java_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 = call_java_cache; | ||
call_java_cache = clp; | ||
} | ||
|
||
static void | ||
lookup_call (const char *p) | ||
{ | ||
|
@@ -1978,6 +1995,11 @@ output_call_cache (void) | |
output_local ("static cob_call_union\tcall_%s;\n", | ||
call->call_name); | ||
} | ||
call_java_cache = call_list_reverse (call_java_cache); | ||
for (call = call_java_cache; call; call = call->next) { | ||
output_local ("static cob_java_handle*\tcall_java_%s;\n", | ||
call->call_name); | ||
} | ||
func_call_cache = call_list_reverse (func_call_cache); | ||
for (call = func_call_cache; call; call = call->next) { | ||
output_local ("static cob_call_union\tfunc_%s;\n", | ||
|
@@ -7068,6 +7090,45 @@ output_field_constant (cb_tree x, int n, const char *flagname) | |
output_newline (); | ||
} | ||
|
||
static void | ||
output_java_call (struct cb_call *p) | ||
{ | ||
if (p->args != NULL || p->call_returning != NULL) { | ||
CB_PENDING ("Java method call with parameters or return values"); | ||
COBC_ABORT (); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please tab-indent and move down to after the variable definitions (C89 compat) this feature itself is part of a different PR, right? |
||
} | ||
char* full_name = (char *)CB_LITERAL(p->name)->data; /* Assume java.prefix (enforced in `parser.y`, rule `call_body`)*/ | ||
char* class_and_method_name = full_name + 5; | ||
char *last_dot; | ||
char *method_name; | ||
const char *class_name; | ||
char* mangled; | ||
|
||
mangled = strdup(class_and_method_name); | ||
nberth marked this conversation as resolved.
Show resolved
Hide resolved
|
||
for (size_t i = 0; i < strlen(mangled) + 1; i++) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. move that |
||
mangled[i] = (mangled[i] == '.') ? '_' : mangled[i]; | ||
} | ||
|
||
last_dot = strrchr(class_and_method_name, '.'); | ||
|
||
*last_dot = '\0'; | ||
method_name = last_dot + 1; | ||
class_name = class_and_method_name; | ||
|
||
lookup_java_call(mangled); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please move this to directly after the mangling loop |
||
output_line("if (call_java_%s == NULL)", mangled); | ||
output_block_open(); | ||
|
||
output_prefix(); | ||
output_line("call_java_%s = ", mangled); | ||
output("cob_resolve_java(\"%s\", \"%s\", \"()V\");", class_name, method_name); | ||
output_newline (); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should all be a single |
||
output_prefix (); | ||
output_line("cob_call_java(call_java_%s);\n", mangled); | ||
output_newline(); | ||
output_block_close(); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do an exception check afterwards, as done for normal calls; also add the |
||
|
||
static void | ||
output_call (struct cb_call *p) | ||
{ | ||
|
@@ -7097,6 +7158,11 @@ output_call (struct cb_call *p) | |
} | ||
system_call = NULL; | ||
|
||
if (p->convention & CB_CONV_JAVA) { | ||
output_java_call(p); | ||
return; | ||
} | ||
|
||
#ifdef _WIN32 | ||
if (p->convention & CB_CONV_STDCALL) { | ||
convention = "_std"; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12253,6 +12253,19 @@ call_body: | |
|
||
/* Check parameter conformance, if we can work out what is being called. */ | ||
if (CB_LITERAL_P ($3)) { | ||
/* Check for "Java." prefix and set call convention */ | ||
char* s = (char *)CB_LITERAL ($3)->data; | ||
if (strncasecmp("Java.", s, 5) == 0) { | ||
call_conv = CB_CONV_JAVA; | ||
/* Check for malformed Java method names */ | ||
if (strchr(s + 5, '.') == NULL) { | ||
cb_error_x ($3, _("malformed Java method name '%s', expected format 'Java.ClassName.methodName'"), s); | ||
GitMensch marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
/* Check for unsupported Java method calls with parameters or return values */ | ||
if($7 != NULL || $8 != NULL) { | ||
CB_PENDING("Java method calls with parameters or return values"); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. move this code to |
||
} | ||
cb_check_conformance ($3, $7, $8); | ||
} else if (CB_REFERENCE_P ($3)) { | ||
cb_tree ref = cb_ref ($3); | ||
|
nberth marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -113,6 +113,8 @@ AH_TEMPLATE([WITH_JSON], [JSON handler]) | |
AH_TEMPLATE([WITH_CJSON], [Use cJSON library/source as JSON handler]) | ||
AH_TEMPLATE([WITH_JSON_C], [Use JSON-C library as JSON handler]) | ||
|
||
AH_TEMPLATE([WITH_JNI], [Support for Java calls through JNI]) | ||
|
||
AH_TEMPLATE([COB_EXPORT_DYN], [Compile/link option for exporting symbols]) | ||
AH_TEMPLATE([COB_PIC_FLAGS], [Compile/link option for PIC code]) | ||
AH_TEMPLATE([COB_DEBUG_FLAGS], [Compile/link option for debugging]) | ||
|
@@ -483,7 +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]) | ||
|
||
|
||
# Checks for typedefs, structures, and compiler characteristics. | ||
AC_C_CONST | ||
AC_C_BIGENDIAN | ||
|
@@ -933,7 +934,73 @@ 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])]) | ||
cob_has_jni=no | ||
AS_IF([test "x$with_java" != "xno"], [ | ||
dnl Find `java` and $JAVA_HOME (we need the latter to locate libjvm). | ||
dnl AX_CHECK_JAVA_HOME dnl (<- does not appear to work properly) | ||
AX_PROG_JAVA | ||
if test "x$JAVA_HOME" = x; then | ||
JAVA_HOME="$( $JAVA -XshowSettings:properties -version 2>&1 >/dev/null | \ | ||
$SED -e '/^[ ]*java.home/!d' -e 's/.*=[ ]*//' )" | ||
AC_MSG_NOTICE([Found Java home: ${JAVA_HOME}]) | ||
else | ||
AC_MSG_NOTICE([Given Java home: ${JAVA_HOME}]) | ||
fi | ||
|
||
dnl Note: AX_PROG_JAVAC might find a `javac` binary that does | ||
dnl not match the version of `$JAVA` found above, so we set | ||
dnl its path manually. | ||
JAVAC="$JAVA_HOME/bin/javac" | ||
AX_PROG_JAVAC_WORKS | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm sure that there are multiple issues with this... I did sent a mail to the original author of those macros to possibly sort some out... For now I suggest to replace the first three lines with manual code using |
||
|
||
AX_JNI_INCLUDE_DIR | ||
AS_IF([test "$JNI_INCLUDE_DIRS" != ""], [ | ||
for JNI_INCLUDE_DIR in $JNI_INCLUDE_DIRS; do | ||
JNI_CPPFLAGS="$JNI_CPPFLAGS -I$JNI_INCLUDE_DIR" | ||
done | ||
Comment on lines
+967
to
+971
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. only do this if |
||
for _dir in "${JAVA_HOME}/jre/lib" "${JAVA_HOME}/lib"; do | ||
if test -d "$_dir"; then | ||
JNI_LIBS="$JNI_LIBS -L$_dir" | ||
fi | ||
nberth marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if test -d "$_dir/server"; then | ||
JNI_LIBS="$JNI_LIBS -L$_dir/server" | ||
fi | ||
if test -d "$_dir/client"; then | ||
JNI_LIBS="$JNI_LIBS -L$_dir/client" | ||
fi | ||
done | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this part should be separate and only set |
||
curr_LIBS="$LIBS" | ||
curr_CPPFLAGS="$CPPFLAGS" | ||
LIBS="$LIBS $JNI_LIBS -ljvm" | ||
CPPFLAGS="$CPPFLAGS $JNI_CPPFLAGS" | ||
AC_MSG_CHECKING([if -ljvm brings JNI symbols]) | ||
AC_LINK_IFELSE([ | ||
AC_LANG_SOURCE([[ | ||
#include <jni.h> | ||
void main (void) { | ||
(void) JNI_CreateJavaVM (NULL, NULL, NULL); | ||
} | ||
]]) | ||
], [ | ||
AC_MSG_RESULT([yes]) | ||
AC_DEFINE([WITH_JNI], [1]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this define should be outside (in the "else" part of the code below, when all checks worked) |
||
JNI_LDFLAGS="$JNI_LIBS" | ||
JNI_LIBS="-ljvm" | ||
cob_has_jni=yes | ||
], [ | ||
AC_MSG_RESULT([no]) | ||
]) | ||
LIBS="$curr_LIBS" | ||
CPPFLAGS="$curr_CPPFLAGS" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this part should be outside and only run if all of the above works (java, javac, jni.h) |
||
]) | ||
]) | ||
AS_IF([test "x$with_java" = "xyes" -a "x$cob_has_jni" != "xyes"], [ | ||
AC_MSG_ERROR([Java interoperability requested, but JNI was not found]) | ||
]) | ||
|
||
# Checks for cjson/json-c. | ||
AC_MSG_NOTICE([Checks for JSON handler]) | ||
|
@@ -2570,6 +2637,8 @@ AM_CONDITIONAL([COB_MAKE_LMDB_LIB], [test "$cob_gen_lmdb" = "yes"]) | |
|
||
AM_CONDITIONAL([LOCAL_CJSON],[test "$USE_JSON" = "local"]) | ||
|
||
AM_CONDITIONAL([COB_HAS_JNI], [test "$cob_has_jni" = "yes"]) | ||
|
||
unset COB_USES_GCC | ||
unset COB_USES_GCC_NO_ICC | ||
unset COB_USES_ICC_ONLY | ||
|
@@ -2660,6 +2729,11 @@ AC_SUBST([OCI_CFLAGS]) | |
AC_SUBST([BDB_CFLAGS]) | ||
AC_SUBST([LMDB_CFLAGS]) | ||
|
||
AC_SUBST([JAVAC]) | ||
AC_SUBST([JNI_LIBS]) | ||
AC_SUBST([JNI_LDFLAGS]) | ||
AC_SUBST([JNI_CPPFLAGS]) | ||
Comment on lines
+2742
to
+2745
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. those should not be directly set to |
||
|
||
dnl was used in bin/Makefile.am - seems not to be needed | ||
dnl AC_SUBST([COB_EXPORT_DYN]) | ||
|
||
|
@@ -2683,6 +2757,7 @@ AC_SUBST([COB_HAS_OCEXTFH]) | |
AC_SUBST([COB_HAS_CURSES]) | ||
AC_SUBST([COB_HAS_XML2]) | ||
AC_SUBST([COB_HAS_JSON]) | ||
AC_SUBST([COB_HAS_JNI]) | ||
AC_SUBST([COB_HAS_64_BIT_POINTER]) | ||
AC_SUBST([COB_PATCH_LEVEL], [$with_patch_level]) # needed for bin/cob-config | ||
|
||
|
@@ -2804,4 +2879,6 @@ case "$USE_JSON" in | |
;; | ||
esac | ||
|
||
AC_MSG_NOTICE([ Build with Java interoperability: ${cob_has_jni}]) | ||
|
||
unset DEFINE_DL |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if supported types are checked in |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2211,6 +2211,7 @@ For a complete list of supported system routines, | |
* CBL_GC_NANOSLEEP:: Sleep for nanoseconds | ||
* CBL_GC_FORK:: Fork the current COBOL process to a new one | ||
* CBL_GC_WAITPID:: Wait for a system process to end | ||
* Java Integration:: Interfacing with Java through JNI | ||
@end menu | ||
|
||
@node CBL_GC_GETOPT | ||
|
@@ -2575,6 +2576,45 @@ is not available on the current system. | |
END-DISPLAY | ||
@end example | ||
|
||
@node Java Integration | ||
@section Java Integration | ||
@cindex Java, JNI, method calls | ||
|
||
GnuCOBOL now supports integration with Java through the Java Native Interface (JNI). This allows COBOL programs to call Java methods directly. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the manual is timeless, so no "now" here; please roughly word-wrap all entries in the file around col80 |
||
|
||
@subsection Supported Method Calls | ||
Currently, only void Java methods with no parameters are supported. Method calls that do not conform to this restriction will result in an error at compile-time. | ||
|
||
@subsection Setting Up Java Integration | ||
To use Java integration, you need to set the `JAVA_HOME` environment variable to point to your Java installation. Additionally, ensure that your `PATH` includes the Java binaries. | ||
|
||
@subsection Error Handling | ||
Any attempt to call Java methods with parameters or expecting return values will result in a compile-time error. The GnuCOBOL compiler will issue a warning if the method name does not follow the `Java.ClassName.methodName` format. | ||
|
||
@subsection Known Limitations | ||
Currently, GnuCOBOL supports only void methods without parameters. Future updates will address these limitations to provide broader Java integration capabilities. | ||
|
||
@subsection Example Usage | ||
Here is an example of a COBOL program calling a Java method: | ||
|
||
@example | ||
IDENTIFICATION DIVISION. | ||
PROGRAM-ID. SampleJavaCall. | ||
PROCEDURE DIVISION. | ||
CALL "Java.com.example.HelloWorld.printMessage". | ||
STOP RUN. | ||
@end example | ||
|
||
Ensure the class `com.example.HelloWorld` is in your classpath and that `printMessage` is a static void method with no parameters. | ||
|
||
@subsection Environment Variables | ||
Set the following environment variables to enable Java integration: | ||
|
||
@example | ||
export JAVA_HOME=/path/to/java | ||
export PATH=$JAVA_HOME/bin:$PATH | ||
@end example | ||
|
||
@node Appendices | ||
|
||
@menu | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NEWS, DEPENDENCIES: updated for JNI