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
--- 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 {