8165634: Support multiple --add-modules options on the command line
authorhseigel
Sat, 10 Sep 2016 08:25:51 -0400
changeset 41073 ed43eecbd166
parent 41072 add84d2b8d09
child 41074 ff67d4b3c085
8165634: Support multiple --add-modules options on the command line Summary: Use numbered properties for --add-module options so that multiple --add-module options can be supported. Reviewed-by: coleenp, gziemski, lfoltan, ccheung
hotspot/src/share/vm/runtime/arguments.cpp
hotspot/src/share/vm/runtime/arguments.hpp
hotspot/test/runtime/modules/ModuleOptionsTest.java
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Fri Sep 09 19:41:41 2016 +0000
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Sat Sep 10 08:25:51 2016 -0400
@@ -1308,35 +1308,13 @@
   return true;
 }
 
-// sets or adds a module name to the jdk.module.addmods property
-bool Arguments::append_to_addmods_property(const char* module_name) {
-  const char* key = "jdk.module.addmods";
-  const char* old_value = Arguments::get_property(key);
-  size_t buf_len = strlen(key) + strlen(module_name) + 2;
-  if (old_value != NULL) {
-    buf_len += strlen(old_value) + 1;
-  }
-  char* new_value = AllocateHeap(buf_len, mtArguments);
-  if (new_value == NULL) {
-    return false;
-  }
-  if (old_value == NULL) {
-    jio_snprintf(new_value, buf_len, "%s=%s", key, module_name);
-  } else {
-    jio_snprintf(new_value, buf_len, "%s=%s,%s", key, old_value, module_name);
-  }
-  bool added = add_property(new_value, UnwriteableProperty, InternalProperty);
-  FreeHeap(new_value);
-  return added;
-}
-
 #if INCLUDE_CDS
 void Arguments::check_unsupported_dumping_properties() {
   assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
   const char* unsupported_properties[5] = { "jdk.module.main",
                                            "jdk.module.path",
                                            "jdk.module.upgrade.path",
-                                           "jdk.module.addmods",
+                                           "jdk.module.addmods.0",
                                            "jdk.module.limitmods" };
   const char* unsupported_options[5] = { "-m",
                                         "--module-path",
@@ -2566,8 +2544,8 @@
 
 unsigned int addreads_count = 0;
 unsigned int addexports_count = 0;
+unsigned int addmods_count = 0;
 unsigned int patch_mod_count = 0;
-const char* add_modules_value = NULL;
 
 bool Arguments::create_property(const char* prop_name, const char* prop_value, PropertyInternal internal) {
   size_t prop_len = strlen(prop_name) + strlen(prop_value) + 2;
@@ -2821,7 +2799,9 @@
         return JNI_ENOMEM;
       }
     } else if (match_option(option, "--add-modules=", &tail)) {
-      add_modules_value = tail;
+      if (!create_numbered_property("jdk.module.addmods", tail, addmods_count++)) {
+        return JNI_ENOMEM;
+      }
     } else if (match_option(option, "--limit-modules=", &tail)) {
       if (!create_property("jdk.module.limitmods", tail, InternalProperty)) {
         return JNI_ENOMEM;
@@ -2873,7 +2853,7 @@
         char *options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(tail) + 1, mtArguments), tail);
         add_init_agent("instrument", options, false);
         // java agents need module java.instrument
-        if (!Arguments::append_to_addmods_property("java.instrument")) {
+        if (!create_numbered_property("jdk.module.addmods", "java.instrument", addmods_count++)) {
           return JNI_ENOMEM;
         }
       }
@@ -3149,7 +3129,7 @@
           return JNI_EINVAL;
         }
         // management agent in module java.management
-        if (!Arguments::append_to_addmods_property("java.management")) {
+        if (!create_numbered_property("jdk.module.addmods", "java.management", addmods_count++)) {
           return JNI_ENOMEM;
         }
 #else
@@ -3560,15 +3540,6 @@
     return JNI_ERR;
   }
 
-  // Append the value of the last --add-modules option specified on the command line.
-  // This needs to be done here, to prevent overwriting possible values written
-  // to the jdk.module.addmods property by -javaagent and other options.
-  if (add_modules_value != NULL) {
-    if (!append_to_addmods_property(add_modules_value)) {
-      return JNI_ENOMEM;
-    }
-  }
-
   // This must be done after all arguments have been processed.
   // java_compiler() true means set to "NONE" or empty.
   if (java_compiler() && !xdebug_mode()) {
@@ -3617,7 +3588,8 @@
 #endif
 
 #if INCLUDE_JVMCI
-  if (EnableJVMCI && !append_to_addmods_property("jdk.vm.ci")) {
+  if (EnableJVMCI &&
+      !create_numbered_property("jdk.module.addmods", "jdk.vm.ci", addmods_count++)) {
     return JNI_ENOMEM;
   }
 #endif
--- a/hotspot/src/share/vm/runtime/arguments.hpp	Fri Sep 09 19:41:41 2016 +0000
+++ b/hotspot/src/share/vm/runtime/arguments.hpp	Sat Sep 10 08:25:51 2016 -0400
@@ -489,9 +489,6 @@
 
   static int process_patch_mod_option(const char* patch_mod_tail, bool* patch_mod_javabase);
 
-  // Miscellaneous system property setter
-  static bool append_to_addmods_property(const char* module_name);
-
   // Aggressive optimization flags.
   static jint set_aggressive_opts_flags();
 
--- a/hotspot/test/runtime/modules/ModuleOptionsTest.java	Fri Sep 09 19:41:41 2016 +0000
+++ b/hotspot/test/runtime/modules/ModuleOptionsTest.java	Sat Sep 10 08:25:51 2016 -0400
@@ -24,8 +24,8 @@
 /*
  * @test
  * @bug 8136930
- * @summary Test that the VM only recognizes the last specified --add-modules
- *          and --list-modules options
+ * @summary Test that the VM only recognizes the last specified --list-modules
+ *          options but accumulates --add-module values.
  * @modules java.base/jdk.internal.misc
  * @library /test/lib
  */
@@ -38,14 +38,16 @@
 
     public static void main(String[] args) throws Exception {
 
-        // Test that last --add-modules is the only one recognized.  No exception
-        // should be thrown.
+        // Test that multiple --add-modules options are cumulative, not last one wins.
+        // An exception should be thrown because module i_dont_exist doesn't exist.
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
             "--add-modules=i_dont_exist", "--add-modules=java.base", "-version");
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
-        output.shouldHaveExitValue(0);
+        output.shouldContain("ResolutionException");
+        output.shouldContain("i_dont_exist");
+        output.shouldHaveExitValue(1);
 
-        // Test that last --limit-modules is the only one recognized.  No exception
+        // Test that the last --limit-modules is the only one recognized.  No exception
         // should be thrown.
         pb = ProcessTools.createJavaProcessBuilder(
             "--limit-modules=i_dont_exist", "--limit-modules=java.base", "-version");