8136552: Last argument wins does not work for special options with "-XX:VMOptionsFile" option
authordcubed
Thu, 15 Oct 2015 10:00:30 -0700
changeset 33220 06fda2285c63
parent 33218 32b706c7c6a0
child 33221 c2d629fd9583
8136552: Last argument wins does not work for special options with "-XX:VMOptionsFile" option Summary: match_special_option_and_act() should insert_vm_options_file() earlier and process the inserted options right away to honor "last option wins" semantics. Reviewed-by: dcubed, coleenp
hotspot/src/share/vm/runtime/arguments.cpp
hotspot/test/runtime/CommandLine/VMOptionsFile/TestVMOptionsFile.java
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Thu Oct 15 13:00:17 2015 +0200
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Thu Oct 15 10:00:30 2015 -0700
@@ -3938,16 +3938,8 @@
     return code;
   }
 
-  // Now set global settings from the vm_option file, giving an error if
-  // it has VMOptionsFile in it
-  code = match_special_option_and_act(vm_options_file_args->get(), flags_file,
-                                      NULL, NULL, NULL);
-  if (code != JNI_OK) {
-    return code;
-  }
-
   if (vm_options_file_args->get()->nOptions < 1) {
-    return 0;
+    return JNI_OK;
   }
 
   return args_out->insert(args, vm_options_file_args->get(),
@@ -3982,17 +3974,29 @@
         // The caller accepts -XX:VMOptionsFile
         if (*vm_options_file != NULL) {
           jio_fprintf(defaultStream::error_stream(),
-                      "Only one VM Options file is supported "
-                      "on the command line\n");
+                      "The VM Options file can only be specified once and "
+                      "only on the command line.\n");
           return JNI_EINVAL;
         }
 
         *vm_options_file = (char *) tail;
         vm_options_file_pos = index;  // save position of -XX:VMOptionsFile
-        if (*vm_options_file == NULL) {
-          jio_fprintf(defaultStream::error_stream(),
-                      "Cannot copy vm_options_file name.\n");
-          return JNI_ENOMEM;
+        // If there's a VMOptionsFile, parse that (also can set flags_file)
+        jint code = insert_vm_options_file(args, flags_file, vm_options_file,
+                                           vm_options_file_pos,
+                                           vm_options_file_args, args_out);
+        if (code != JNI_OK) {
+          return code;
+        }
+        if (args_out->is_set()) {
+          // The VMOptions file inserted some options so switch 'args'
+          // to the new set of options, and continue processing which
+          // preserves "last option wins" semantics.
+          args = args_out->get();
+          // The first option from the VMOptionsFile replaces the
+          // current option.  So we back track to process the
+          // replacement option.
+          index--;
         }
       } else {
         jio_fprintf(defaultStream::error_stream(),
@@ -4052,12 +4056,6 @@
     }
 #endif
   }
-
-  // If there's a VMOptionsFile, parse that (also can set flags_file)
-  if ((vm_options_file != NULL) && (*vm_options_file != NULL)) {
-    return insert_vm_options_file(args, flags_file, vm_options_file,
-                                  vm_options_file_pos, vm_options_file_args, args_out);
-  }
   return JNI_OK;
 }
 
--- a/hotspot/test/runtime/CommandLine/VMOptionsFile/TestVMOptionsFile.java	Thu Oct 15 13:00:17 2015 +0200
+++ b/hotspot/test/runtime/CommandLine/VMOptionsFile/TestVMOptionsFile.java	Thu Oct 15 10:00:30 2015 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8061999
+ * @bug 8061999 8135195 8136552
  * @summary Test "-XX:VMOptionsFile" VM option
  * @library /testlibrary
  * @modules jdk.management
@@ -478,6 +478,7 @@
         runJavaCheckExitValue(pb, JVM_SUCCESS);
 
         outputShouldContain("interpreted mode");
+        outputShouldNotContain("VM option '+PrintVMOptions'");
         checkProperty("shared.property", "command_line_after");
         checkVMOption("MinHeapFreeRatio", "9");
 
@@ -547,13 +548,13 @@
         addVMOptionsFile(VM_OPTION_FILE_WITH_SAME_VM_OPTION_FILE);
 
         runJavaCheckExitValue(JVM_FAIL_WITH_EXIT_CODE_1);
-        outputShouldContain("VM options file is only supported on the command line");
+        outputShouldContain("The VM Options file can only be specified once and only on the command line.");
 
         /* Pass VM option file with VM option file option in it */
         addVMOptionsFile(VM_OPTION_FILE_WITH_VM_OPTION_FILE);
 
         runJavaCheckExitValue(JVM_FAIL_WITH_EXIT_CODE_1);
-        outputShouldContain("VM options file is only supported on the command line");
+        outputShouldContain("The VM Options file can only be specified once and only on the command line.");
 
         /* Pass VM option file which is not accessible (without read permissions) */
         addVMOptionsFile(getAbsolutePathFromSource(VM_OPTION_FILE_WITHOUT_READ_PERMISSIONS));
@@ -566,7 +567,7 @@
         addVMOptionsFile(VM_OPTION_FILE_2);
 
         runJavaCheckExitValue(JVM_FAIL_WITH_EXIT_CODE_1);
-        outputShouldContain("Only one VM Options file is supported on the command line");
+        outputShouldContain("The VM Options file can only be specified once and only on the command line.");
 
         /* Pass empty option file i.e. pass "-XX:VMOptionsFile=" */
         addVMOptionsFile("");
@@ -585,6 +586,22 @@
 
         runJavaCheckExitValue(JVM_FAIL_WITH_EXIT_CODE_1);
         outputShouldContain("Unmatched quote in");
+
+        /* Pass VM Option file in _JAVA_OPTIONS environment variable */
+        pb = createProcessBuilder();
+
+        updateEnvironment(pb, JAVA_OPTIONS, "-XX:VMOptionsFile=" + getAbsolutePathFromSource(VM_OPTION_FILE_1));
+
+        runJavaCheckExitValue(pb, JVM_FAIL_WITH_EXIT_CODE_1);
+        outputShouldContain("VM options file is only supported on the command line");
+
+        /* Pass VM Option file in JAVA_TOOL_OPTIONS environment variable */
+        pb = createProcessBuilder();
+
+        updateEnvironment(pb, JAVA_TOOL_OPTIONS, "-XX:VMOptionsFile=" + getAbsolutePathFromSource(VM_OPTION_FILE_1));
+
+        runJavaCheckExitValue(pb, JVM_FAIL_WITH_EXIT_CODE_1);
+        outputShouldContain("VM options file is only supported on the command line");
     }
 
     public static void main(String[] args) throws Exception {