< prev index next >

src/java.base/share/native/libjava/Module.c

Print this page
rev 16428 : 8171855: Move package name transformations during module bootstrap into native code
Reviewed-by: alanb, acorn, lfoltan, mchung, plevart, hseigel, sspitsyn

@@ -20,22 +20,92 @@
  *
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+#include <stdlib.h>
+#include <string.h>
 
 #include "jni.h"
+#include "jni_util.h"
 #include "jvm.h"
 
 #include "java_lang_reflect_Module.h"
 
+/*
+ * Gets the UTF-8 chars for the string and translates '.' to '/'.  Does no
+ * further validation, assumption being that both calling code in
+ * java.lang.reflect.Module and VM will do deeper validation.
+ */
+static char*
+GetInternalPackageName(JNIEnv *env, jstring pkg, char* buf, jsize buf_size)
+{
+    jsize len;
+    jsize unicode_len;
+    char* p;
+    char* utf_str;
+
+    len = (*env)->GetStringUTFLength(env, pkg);
+    unicode_len = (*env)->GetStringLength(env, pkg);
+    if (len >= buf_size) {
+        utf_str = malloc(len + 1);
+        if (utf_str == NULL) {
+            JNU_ThrowOutOfMemoryError(env, NULL);
+            return NULL;
+        }
+    } else {
+        utf_str = buf;
+    }
+    (*env)->GetStringUTFRegion(env, pkg, 0, unicode_len, utf_str);
+
+    p = utf_str;
+    while (*p != '\0') {
+        if (*p == '.') {
+            *p = '/';
+        }
+        p++;
+    }
+    return utf_str;
+}
+
 JNIEXPORT void JNICALL
 Java_java_lang_reflect_Module_defineModule0(JNIEnv *env, jclass cls, jobject module,
                                             jboolean is_open, jstring version,
                                             jstring location, jobjectArray packages)
 {
-    JVM_DefineModule(env, module, is_open, version, location, packages);
+    char** pkgs = NULL;
+    jsize idx;
+    jsize num_packages = (*env)->GetArrayLength(env, packages);
+
+    if (num_packages != 0 && (pkgs = calloc(num_packages, sizeof(char*))) == NULL) {
+        JNU_ThrowOutOfMemoryError(env, NULL);
+        return;
+    } else {
+        int valid = 1;
+        for (idx = 0; idx < num_packages; idx++) {
+            jstring pkg = (*env)->GetObjectArrayElement(env, packages, idx);
+            pkgs[idx] = GetInternalPackageName(env, pkg, NULL, 0);
+            if (pkgs[idx] == NULL) {
+                valid = 0;
+                break;
+            }
+        }
+
+        if (valid != 0) {
+            JVM_DefineModule(env, module, is_open, version, location,
+                    (const char* const*)pkgs, num_packages);
+        }
+    }
+
+    if (num_packages > 0) {
+        for (idx = 0; idx < num_packages; idx++) {
+            if (pkgs[idx] != NULL) {
+                free(pkgs[idx]);
+            }
+        }
+        free(pkgs);
+    }
 }
 
 JNIEXPORT void JNICALL
 Java_java_lang_reflect_Module_addReads0(JNIEnv *env, jclass cls, jobject from, jobject to)
 {

@@ -44,27 +114,83 @@
 
 JNIEXPORT void JNICALL
 Java_java_lang_reflect_Module_addExports0(JNIEnv *env, jclass cls, jobject from,
                                           jstring pkg, jobject to)
 {
-    JVM_AddModuleExports(env, from, pkg, to);
+    char buf[128];
+    char* pkg_name;
+
+    if (pkg == NULL) {
+        JNU_ThrowNullPointerException(env, "package is null");
+        return;
+    }
+
+    pkg_name = GetInternalPackageName(env, pkg, buf, (jsize)sizeof(buf));
+    if (pkg_name != NULL) {
+        JVM_AddModuleExports(env, from, pkg_name, to);
+        if (pkg_name != buf) {
+            free(pkg_name);
+        }
+    }
 }
 
 JNIEXPORT void JNICALL
 Java_java_lang_reflect_Module_addExportsToAll0(JNIEnv *env, jclass cls, jobject from,
                                                jstring pkg)
 {
-    JVM_AddModuleExportsToAll(env, from, pkg);
+    char buf[128];
+    char* pkg_name;
+
+    if (pkg == NULL) {
+        JNU_ThrowNullPointerException(env, "package is null");
+        return;
+    }
+
+    pkg_name = GetInternalPackageName(env, pkg, buf, (jsize)sizeof(buf));
+    if (pkg_name != NULL) {
+        JVM_AddModuleExportsToAll(env, from, pkg_name);
+        if (pkg_name != buf) {
+            free(pkg_name);
+        }
+    }
 }
 
 JNIEXPORT void JNICALL
 Java_java_lang_reflect_Module_addExportsToAllUnnamed0(JNIEnv *env, jclass cls,
                                                       jobject from, jstring pkg)
 {
-    JVM_AddModuleExportsToAllUnnamed(env, from, pkg);
+    char buf[128];
+    char* pkg_name;
+
+    if (pkg == NULL) {
+        JNU_ThrowNullPointerException(env, "package is null");
+        return;
+    }
+
+    pkg_name = GetInternalPackageName(env, pkg, buf, (jsize)sizeof(buf));
+    if (pkg_name != NULL) {
+        JVM_AddModuleExportsToAllUnnamed(env, from, pkg_name);
+        if (pkg_name != buf) {
+            free(pkg_name);
+        }
+    }
 }
 
 JNIEXPORT void JNICALL
 Java_java_lang_reflect_Module_addPackage0(JNIEnv *env, jclass cls, jobject m, jstring pkg)
 {
-    JVM_AddModulePackage(env, m, pkg);
+    char buf[128];
+    char* pkg_name;
+
+    if (pkg == NULL) {
+        JNU_ThrowNullPointerException(env, "package is null");
+        return;
+    }
+
+    pkg_name = GetInternalPackageName(env, pkg, buf, (jsize)sizeof(buf));
+    if (pkg_name != NULL) {
+        JVM_AddModulePackage(env, m, pkg_name);
+        if (pkg_name != buf) {
+            free(pkg_name);
+        }
+    }
 }
< prev index next >