diff --git a/cobc/codegen.c b/cobc/codegen.c index 63d80f206..d3e6f36aa 100644 --- a/cobc/codegen.c +++ b/cobc/codegen.c @@ -7113,44 +7113,51 @@ output_exception_handling(struct cb_call *p) } static void -output_java_call (struct cb_call *p) +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 (); - } - 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; - size_t i; + if (p->args != NULL || p->call_returning != NULL) { + CB_PENDING("Java method call with parameters or return values"); + COBC_ABORT(); + } - mangled = strdup(class_and_method_name); - for (i = 0; i < strlen(mangled) + 1; i++) { - mangled[i] = (mangled[i] == '.') ? '_' : mangled[i]; - } + 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; + + // Directly duplicate the class_and_method_name + mangled = strdup(class_and_method_name); + if (!mangled) { + cobc_err_msg(_("Memory allocation failed for mangled name")); + COBC_ABORT(); + } - lookup_java_call(mangled); + lookup_java_call(mangled); - last_dot = strrchr(class_and_method_name, '.'); + last_dot = strrchr(class_and_method_name, '.'); - *last_dot = '\0'; - method_name = last_dot + 1; - class_name = class_and_method_name; + if (last_dot == NULL) { + cobc_err_msg(_("malformed call '%s' to a Java method"), class_and_method_name); + cobc_free(mangled); + return; + } - output_line("if (call_java_%s == NULL)", mangled); - output_block_open(); + *last_dot = '\0'; + method_name = last_dot + 1; + class_name = class_and_method_name; - output_line("call_java_%s = cob_resolve_java(\"%s\", \"%s\", \"()V\");", mangled, class_name, method_name); - output_line("cob_call_java(call_java_%s);\n", mangled); - output_newline(); - output_block_close(); - output_exception_handling(p); + output_line("if (call_java_%s == NULL)", mangled); + output_block_open(); - cobc_free((char*) mangled); + output_line("call_java_%s = cob_resolve_java(\"%s\", \"%s\", \"()V\");", mangled, class_name, method_name); + output_line("cob_call_java(call_java_%s);\n", mangled); + output_newline(); + output_block_close(); + output_exception_handling(p); + cobc_free(mangled); } static void diff --git a/libcob/java.c b/libcob/java.c index 893c97711..e414ebef4 100644 --- a/libcob/java.c +++ b/libcob/java.c @@ -45,7 +45,7 @@ jvm_load (void) { JavaVMOption* options; const char *classpath; size_t option_len; - char option_buffer[1024]; + char option_buffer[COB_NORMAL_BUFF]; args.version = JNI_VERSION_1_6; char *classpath = getenv("CLASSPATH"); @@ -77,12 +77,6 @@ resolve_java (const char *class_name, cob_java_handle *handle; char *jni_class_name = strdup(class_name); - for (char *p = jni_class_name; *p; ++p) { - if (*p == '.') { - *p = '/'; - } - } - cls = (*env)->FindClass(env, jni_class_name); cob_free(jni_class_name); if (!cls) { diff --git a/tests/testsuite.src/run_java.at b/tests/testsuite.src/run_java.at index 3b331d4a3..8c9a76031 100644 --- a/tests/testsuite.src/run_java.at +++ b/tests/testsuite.src/run_java.at @@ -131,4 +131,39 @@ AT_DATA([prog.cob], [ AT_CHECK([$COMPILE prog.cob], [0], [], []) AT_CHECK([$COBCRUN_DIRECT ./prog], [0], [], [java call not successful ]) +AT_CLEANUP + +AT_SETUP([CALL Java static void (void) in a package]) +AT_KEYWORDS([extensions jni package]) + +AT_SKIP_IF([test "$COB_HAS_JNI" = "no"]) + +AT_DATA([testpackage/Test.java], [ +package testpackage; +public class Test { + public static void printHelloPackage () { + System.out.println("Hello from package!"); + } +} +]) + +AT_DATA([prog.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + PROCEDURE DIVISION. + CALL "Java.testpackage.Test.printHelloPackage" + NOT ON EXCEPTION + DISPLAY "Java call to package class worked" + END-CALL + STOP RUN. +]) + +AT_CHECK([mkdir -p testpackage]) +AT_CHECK([$JAVAC testpackage/Test.java], [0], [], []) +AT_CHECK([$COMPILE prog.cob], [0], [], []) +AT_CHECK([$COBCRUN_DIRECT ./prog], [0], +[Hello from package! +Java call to package class worked +]) + AT_CLEANUP \ No newline at end of file