1 /* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 8061999 8135195 8136552 27 * @summary Test "-XX:VMOptionsFile" VM option 28 * @library /testlibrary 29 * @modules jdk.management 30 * @run main TestVMOptionsFile 31 */ 32 33 import java.io.File; 34 import java.io.FileWriter; 35 import java.io.IOException; 36 import java.nio.file.Files; 37 import java.nio.file.Paths; 38 import java.nio.file.Path; 39 import java.nio.file.attribute.PosixFilePermissions; 40 import java.nio.file.attribute.AclEntry; 41 import java.nio.file.attribute.AclEntryPermission; 42 import java.nio.file.attribute.AclEntryType; 43 import java.nio.file.attribute.AclFileAttributeView; 44 import java.nio.file.attribute.UserPrincipal; 45 import java.nio.file.StandardCopyOption; 46 import java.util.ArrayList; 47 import java.util.Arrays; 48 import java.util.LinkedHashSet; 49 import java.util.List; 50 import java.util.Properties; 51 import java.util.Set; 52 import jdk.test.lib.Asserts; 53 import jdk.test.lib.DynamicVMOption; 54 import jdk.test.lib.OutputAnalyzer; 55 import jdk.test.lib.ProcessTools; 56 57 public class TestVMOptionsFile { 58 59 /* Various valid VM Option files */ 60 private static final String VM_OPTION_FILE_EMPTY = "optionfile_empty"; 61 private static final String VM_OPTION_FILE_TABS_AND_SPACES = "optionfile_only_tabsandspaces"; 62 private static final String VM_OPTION_FILE_1 = "optionfile_1"; 63 private static final String VM_OPTION_FILE_2 = "optionFILE_2"; 64 private static final String VM_OPTION_FILE_3 = "optionfile_3"; 65 private static final String VM_OPTION_FILE_QUOTE = "optionfile_quote"; 66 private static final String VM_OPTION_FILE_BIG = "optionfile_big"; 67 private static final int REPEAT_COUNT = 512; 68 /* Name of the file with flags for VM_OPTION_FILE_2 Option file */ 69 private static final String FLAGS_FILE = "flags_file"; 70 /* VM Option file with a lot of options with quote on separate lines */ 71 private static final String VM_OPTION_FILE_LOT_OF_OPTIONS_QUOTE = "optionfile_lot_of_options_quote"; 72 /* Number of properties defined in VM_OPTION_FILE_LOT_OF_OPTIONS_QUOTE */ 73 private static final int NUM_OF_PROP_IN_FILE_LOT_OF_OPTIONS_QUOTE = 70; 74 /* VM Option file with long property */ 75 private static final String VM_OPTION_FILE_WITH_LONG_PROPERTY = "optionfile_long_property"; 76 private static final String LONG_PROPERTY_NAME = "veryl'" + String.format("%1536s", "").replace(' ', 'o') + "ng'name"; 77 private static final String LONG_PROPERTY_VALUE = String.format("%2096s", "").replaceAll(" ", "long"); 78 /* 2 VM Option files with unmatched quotes */ 79 private static final String VM_OPTION_FILE_UNMATCHED_QUOTE_1 = "optionfile_unmatched_quote_1"; 80 private static final String VM_OPTION_FILE_UNMATCHED_QUOTE_2 = "optionfile_unmatched_quote_2"; 81 /* VM Option file with bad option in it */ 82 private static final String VM_OPTION_FILE_WITH_BAD_OPTION = "optionfile_bad_option"; 83 /* VM Option file with "-XX:VMOptionsFile=" option in it */ 84 private static final String VM_OPTION_FILE_WITH_VM_OPTION_FILE = "optionfile_with_optionfile"; 85 /* VM Option file with "-XX:VMOptionsFile=" option in it, where file is the same option file */ 86 private static final String VM_OPTION_FILE_WITH_SAME_VM_OPTION_FILE = "optionfile_with_same_optionfile"; 87 /* VM Option file without read permissions(not accessible) */ 88 private static final String VM_OPTION_FILE_WITHOUT_READ_PERMISSIONS = "optionfile_wo_read_perm"; 89 /* VM Option file which does not exist */ 90 private static final String NOT_EXISTING_FILE = "not_exist_junk2123"; 91 92 /* JAVA_TOOL_OPTIONS environment variable */ 93 private static final String JAVA_TOOL_OPTIONS = "JAVA_TOOL_OPTIONS"; 94 /* _JAVA_OPTIONS environment variable */ 95 private static final String JAVA_OPTIONS = "_JAVA_OPTIONS"; 96 97 /* Exit code for JVM, zero - for success, non-zero for failure */ 98 private static final int JVM_SUCCESS = 0; 99 private static final int JVM_FAIL_WITH_EXIT_CODE_1 = 1; 100 101 /* Current working directory */ 102 private static final String CURRENT_DIR = System.getProperty("user.dir"); 103 104 /* Source directory */ 105 private static final String SOURCE_DIR = System.getProperty("test.src", "."); 106 107 /* VM Options which are passed to the JVM */ 108 private static final List<String> VMParams = new ArrayList<>(); 109 /* Argument passed to the PrintPropertyAndOptions.main */ 110 private static final Set<String> appParams = new LinkedHashSet<>(); 111 112 private static OutputAnalyzer output; 113 114 private static final String PRINT_PROPERTY_FORMAT = "Property %s=%s"; 115 private static final String PRINT_VM_OPTION_FORMAT = "Virtual Machine option %s=%s"; 116 117 /* 118 * Get absoulte path to file from folder with sources 119 */ 120 private static String getAbsolutePathFromSource(String fileName) { 121 return SOURCE_DIR + File.separator + fileName; 122 } 123 124 /* 125 * Make file non-readable by modifying its permissions. 126 * If file supports "posix" attributes, then modify it. 127 * Otherwise check for "acl" attributes. 128 */ 129 private static void makeFileNonReadable(String file) throws IOException { 130 Path filePath = Paths.get(file); 131 Set<String> supportedAttr = filePath.getFileSystem().supportedFileAttributeViews(); 132 133 if (supportedAttr.contains("posix")) { 134 Files.setPosixFilePermissions(filePath, PosixFilePermissions.fromString("-w--w----")); 135 } else if (supportedAttr.contains("acl")) { 136 UserPrincipal fileOwner = Files.getOwner(filePath); 137 138 AclFileAttributeView view = Files.getFileAttributeView(filePath, AclFileAttributeView.class); 139 140 AclEntry entry = AclEntry.newBuilder() 141 .setType(AclEntryType.DENY) 142 .setPrincipal(fileOwner) 143 .setPermissions(AclEntryPermission.READ_DATA) 144 .build(); 145 146 List<AclEntry> acl = view.getAcl(); 147 acl.add(0, entry); 148 view.setAcl(acl); 149 } 150 } 151 152 private static void copyFromSource(String fileName) throws IOException { 153 Files.copy(Paths.get(getAbsolutePathFromSource(fileName)), 154 Paths.get(fileName), StandardCopyOption.REPLACE_EXISTING); 155 } 156 157 private static void createOptionFiles() throws IOException { 158 FileWriter fw = new FileWriter(VM_OPTION_FILE_WITH_VM_OPTION_FILE); 159 160 /* Create VM option file with following parameters "-XX:VMOptionFile=<absolute_path_to_the_VM_option_file> */ 161 fw.write("-XX:VMOptionsFile=" + getAbsolutePathFromSource(VM_OPTION_FILE_1)); 162 fw.close(); 163 164 /* Create VM option file with following parameters "-XX:MinHeapFreeRatio=12 -XX:VMOptionFile=<absolute_path_to_the_same_VM_option_file> */ 165 fw = new FileWriter(VM_OPTION_FILE_WITH_SAME_VM_OPTION_FILE); 166 fw.write("-XX:MinHeapFreeRatio=12 -XX:VMOptionsFile=" + (new File(VM_OPTION_FILE_WITH_SAME_VM_OPTION_FILE)).getCanonicalPath()); 167 fw.close(); 168 169 /* Create VM option file with long property */ 170 fw = new FileWriter(VM_OPTION_FILE_WITH_LONG_PROPERTY); 171 fw.write("-D" + LONG_PROPERTY_NAME + "=" + LONG_PROPERTY_VALUE); 172 fw.close(); 173 174 /* Create big VM option file */ 175 fw = new FileWriter(VM_OPTION_FILE_BIG); 176 fw.write("-XX:MinHeapFreeRatio=17\n"); 177 for (int i = 0; i < REPEAT_COUNT; i++) { 178 if (i == REPEAT_COUNT / 2) { 179 fw.write("-XX:+PrintVMOptions "); 180 } 181 fw.write("-Dmy.property=value" + (i + 1) + "\n"); 182 } 183 fw.write("-XX:MaxHeapFreeRatio=85\n"); 184 fw.close(); 185 186 /* Copy valid VM option file and change its permission to make it not accessible */ 187 Files.copy(Paths.get(getAbsolutePathFromSource(VM_OPTION_FILE_1)), 188 Paths.get(VM_OPTION_FILE_WITHOUT_READ_PERMISSIONS), 189 StandardCopyOption.REPLACE_EXISTING); 190 191 makeFileNonReadable(VM_OPTION_FILE_WITHOUT_READ_PERMISSIONS); 192 193 /* Copy valid VM option file to perform test with relative path */ 194 copyFromSource(VM_OPTION_FILE_2); 195 196 /* Copy flags file to the current working folder */ 197 copyFromSource(FLAGS_FILE); 198 199 /* Create a new empty file */ 200 new File(VM_OPTION_FILE_EMPTY).createNewFile(); 201 } 202 203 /* 204 * Add parameters to the VM Parameters list 205 */ 206 private static void addVMParam(String... params) { 207 VMParams.addAll(Arrays.asList(params)); 208 } 209 210 /* 211 * Add VM option name to the application arguments list 212 */ 213 private static void addVMOptionsToCheck(String... params) { 214 for (String param : params) { 215 appParams.add("vmoption=" + param); 216 } 217 } 218 219 /* 220 * Add property to the VM Params list and to the application arguments list 221 */ 222 private static void addProperty(String propertyName, String propertyValue) { 223 addVMParam("-D" + propertyName + "=" + propertyValue); 224 } 225 226 /* 227 * Add "-XX:VMOptionsfile" parameter to the VM Params list 228 */ 229 private static void addVMOptionsFile(String fileName) { 230 addVMParam("-XX:VMOptionsFile=" + fileName); 231 } 232 233 private static void outputShouldContain(String expectedString) { 234 output.shouldContain(expectedString); 235 } 236 237 private static void outputShouldNotContain(String expectedString) { 238 output.shouldNotContain(expectedString); 239 } 240 241 private static ProcessBuilder createProcessBuilder() throws Exception { 242 ProcessBuilder pb; 243 List<String> runJava = new ArrayList<>(); 244 245 runJava.addAll(VMParams); 246 runJava.add(PrintPropertyAndOptions.class.getName()); 247 runJava.addAll(appParams); 248 249 pb = ProcessTools.createJavaProcessBuilder(runJava.toArray(new String[0])); 250 251 VMParams.clear(); 252 appParams.clear(); 253 254 return pb; 255 } 256 257 private static void runJavaCheckExitValue(ProcessBuilder pb, int expectedExitValue) throws Exception { 258 output = new OutputAnalyzer(pb.start()); 259 output.shouldHaveExitValue(expectedExitValue); 260 } 261 262 private static void runJavaCheckExitValue(int expectedExitValue) throws Exception { 263 runJavaCheckExitValue(createProcessBuilder(), expectedExitValue); 264 } 265 266 /* 267 * Update environment variable in passed ProcessBuilder object to the passed value 268 */ 269 private static void updateEnvironment(ProcessBuilder pb, String name, String value) { 270 pb.environment().put(name, value); 271 } 272 273 /* 274 * Check property value by examining output 275 */ 276 private static void checkProperty(String property, String expectedValue) { 277 outputShouldContain(String.format(PRINT_PROPERTY_FORMAT, property, expectedValue)); 278 } 279 280 /* 281 * Check VM Option value by examining output 282 */ 283 private static void checkVMOption(String vmOption, String expectedValue) { 284 outputShouldContain(String.format(PRINT_VM_OPTION_FORMAT, vmOption, expectedValue)); 285 } 286 287 private static void testVMOptions() throws Exception { 288 /* Check that empty VM Option file is accepted without errors */ 289 addVMOptionsFile(VM_OPTION_FILE_EMPTY); 290 291 runJavaCheckExitValue(JVM_SUCCESS); 292 293 /* Check that VM Option file with tabs and spaces is accepted without errors */ 294 addVMOptionsFile(getAbsolutePathFromSource(VM_OPTION_FILE_TABS_AND_SPACES)); 295 296 runJavaCheckExitValue(JVM_SUCCESS); 297 298 /* Check that parameters are gotten from first VM Option file. Pass absolute path to the VM Option file */ 299 addVMParam("-showversion"); 300 addVMOptionsFile(getAbsolutePathFromSource(VM_OPTION_FILE_1)); 301 addVMOptionsToCheck("SurvivorRatio", "MinHeapFreeRatio"); 302 303 runJavaCheckExitValue(JVM_SUCCESS); 304 outputShouldContain("interpreted mode"); 305 checkProperty("optfile_1", "option_file_1"); 306 checkVMOption("SurvivorRatio", "16"); 307 checkVMOption("MinHeapFreeRatio", "22"); 308 309 /* 310 * Check that parameters are gotten from second VM Option file which also contains flags file. 311 * Flags file and option file contains NewRatio, but since options from VM Option file 312 * are processed later NewRatio should be set to value from VM Option file 313 * Pass relative path to the VM Option file in form "vmoptionfile" 314 */ 315 addVMOptionsFile(VM_OPTION_FILE_2); 316 addVMOptionsToCheck("UseGCOverheadLimit", "NewRatio", "MinHeapFreeRatio", "MaxFDLimit", "AlwaysPreTouch"); 317 318 runJavaCheckExitValue(JVM_SUCCESS); 319 checkProperty("javax.net.ssl.keyStorePassword", "someVALUE123+"); 320 checkVMOption("UseGCOverheadLimit", "true"); 321 checkVMOption("NewRatio", "4"); 322 checkVMOption("MinHeapFreeRatio", "3"); 323 checkVMOption("MaxFDLimit", "true"); 324 checkVMOption("AlwaysPreTouch", "false"); 325 326 /* Check that parameters are gotten from third VM Option file which contains a mix of the options */ 327 addVMParam("-showversion"); 328 addVMOptionsFile(getAbsolutePathFromSource(VM_OPTION_FILE_3)); 329 addVMOptionsToCheck("UseGCOverheadLimit", "NewRatio"); 330 331 runJavaCheckExitValue(JVM_SUCCESS); 332 outputShouldContain("interpreted mode"); 333 checkProperty("other.secret.data", "qwerty"); 334 checkProperty("property", "second"); 335 checkVMOption("UseGCOverheadLimit", "false"); 336 checkVMOption("NewRatio", "16"); 337 338 /* Check that quotes are processed normally in VM Option file */ 339 addVMParam("-showversion"); 340 addVMOptionsFile(getAbsolutePathFromSource(VM_OPTION_FILE_QUOTE)); 341 addVMOptionsToCheck("ErrorFile"); 342 343 runJavaCheckExitValue(JVM_SUCCESS); 344 345 outputShouldContain("interpreted mode"); 346 checkProperty("my.quote.single", "Property in single quote. Here a double qoute\" Add some slashes \\/"); 347 checkProperty("my.quote.double", "Double qoute. Include single '."); 348 checkProperty("javax.net.ssl.trustStorePassword", "data @+NEW"); 349 checkVMOption("ErrorFile", "./my error file"); 350 351 /* 352 * Verify that VM Option file accepts a file with 70 properties and with two options on separate 353 * lines and properties that use quotes a lot. 354 */ 355 addVMOptionsFile(getAbsolutePathFromSource(VM_OPTION_FILE_LOT_OF_OPTIONS_QUOTE)); 356 addVMOptionsToCheck("MinHeapFreeRatio", "MaxHeapFreeRatio"); 357 358 runJavaCheckExitValue(JVM_SUCCESS); 359 360 for (int i = 1; i <= NUM_OF_PROP_IN_FILE_LOT_OF_OPTIONS_QUOTE; i++) { 361 checkProperty(String.format("prop%02d", i), String.format("%02d", i)); 362 } 363 checkVMOption("MinHeapFreeRatio", "7"); 364 checkVMOption("MaxHeapFreeRatio", "96"); 365 366 /* 367 * Verify that VM Option file accepts a file with very long property. 368 */ 369 addVMOptionsFile(VM_OPTION_FILE_WITH_LONG_PROPERTY); 370 371 runJavaCheckExitValue(JVM_SUCCESS); 372 373 checkProperty(LONG_PROPERTY_NAME.replaceAll("'", ""), LONG_PROPERTY_VALUE); 374 375 /* 376 * Verify that VM Option file accepts a big VM Option file 377 */ 378 addVMOptionsFile(VM_OPTION_FILE_BIG); 379 addVMOptionsToCheck("MinHeapFreeRatio"); 380 addVMOptionsToCheck("MaxHeapFreeRatio"); 381 382 runJavaCheckExitValue(JVM_SUCCESS); 383 384 outputShouldContain("VM option '+PrintVMOptions'"); 385 checkProperty("my.property", "value" + REPEAT_COUNT); 386 checkVMOption("MinHeapFreeRatio", "17"); 387 checkVMOption("MaxHeapFreeRatio", "85"); 388 } 389 390 private static ProcessBuilder prepareTestCase(int testCase) throws Exception { 391 ProcessBuilder pb; 392 393 Asserts.assertTrue(0 < testCase && testCase < 6, "testCase should be from 1 to 5"); 394 395 addVMParam("-showversion"); 396 addVMOptionsToCheck("MinHeapFreeRatio", "SurvivorRatio", "NewRatio"); 397 398 if (testCase < 5) { 399 addVMParam("-XX:Flags=flags_file", "-XX:-PrintVMOptions"); 400 addProperty("shared.property", "command_line_before"); 401 addProperty("clb", "unique_command_line_before"); 402 addVMParam("-XX:MinHeapFreeRatio=7"); 403 } 404 405 if (testCase < 4) { 406 addVMOptionsFile(getAbsolutePathFromSource(VM_OPTION_FILE_1)); 407 } 408 409 if (testCase < 3) { 410 addVMParam("-XX:MinHeapFreeRatio=9", "-XX:-PrintVMOptions"); 411 addProperty("shared.property", "command_line_after"); 412 addProperty("cla", "unique_command_line_after"); 413 } 414 415 /* Create ProcessBuilder after all setup is done to update environment variables */ 416 pb = createProcessBuilder(); 417 418 if (testCase < 2) { 419 updateEnvironment(pb, JAVA_OPTIONS, "-Dshared.property=somevalue -Djo=unique_java_options " 420 + "-XX:MinHeapFreeRatio=18 -Dshared.property=java_options -XX:MinHeapFreeRatio=11 -XX:+PrintVMOptions"); 421 } 422 423 if (testCase < 6) { 424 updateEnvironment(pb, JAVA_TOOL_OPTIONS, "-Dshared.property=qwerty -Djto=unique_java_tool_options " 425 + "-XX:MinHeapFreeRatio=15 -Dshared.property=java_tool_options -XX:MinHeapFreeRatio=6 -XX:+PrintVMOptions"); 426 } 427 428 return pb; 429 } 430 431 private static void testVMOptionsLastArgumentsWins() throws Exception { 432 ProcessBuilder pb; 433 434 /* 435 * "shared.property" property and "MinHeapFreeRatio" XX VM Option are defined 436 * in flags file, JAVA_TOOL_OPTIONS and _JAVA_OPTIONS environment variables, 437 * on command line before VM Option file, on command line after VM Option file 438 * and also in VM Option file. Verify that last argument wins. Also check 439 * unique properties and VM Options. 440 * Here is the order of options processing and last argument wins: 441 * 1) Flags file 442 * 2) JAVA_TOOL_OPTIONS environment variables 443 * 3) Pseudo command line from launcher 444 * 4) _JAVA_OPTIONS 445 * In every category arguments processed from left to right and from up to down 446 * and the last processed arguments wins, i.e. if argument is defined several 447 * times the value of argument will be equal to the last processed argument. 448 * 449 * "shared.property" property and "MinHeapFreeRatio" should be equal to the 450 * value from _JAVA_OPTIONS environment variable 451 */ 452 pb = prepareTestCase(1); 453 454 runJavaCheckExitValue(pb, JVM_SUCCESS); 455 456 outputShouldContain("interpreted mode"); 457 outputShouldContain("VM option '+PrintVMOptions'"); 458 checkProperty("shared.property", "java_options"); 459 checkVMOption("MinHeapFreeRatio", "11"); 460 /* Each category defines its own properties */ 461 checkProperty("jto", "unique_java_tool_options"); 462 checkProperty("jo", "unique_java_options"); 463 checkProperty("clb", "unique_command_line_before"); 464 checkProperty("optfile_1", "option_file_1"); 465 checkProperty("cla", "unique_command_line_after"); 466 /* SurvivorRatio defined only in VM Option file */ 467 checkVMOption("SurvivorRatio", "16"); 468 /* NewRatio defined only in flags file */ 469 checkVMOption("NewRatio", "5"); 470 471 /* 472 * The same as previous but without _JAVA_OPTIONS environment variable. 473 * "shared.property" property and "MinHeapFreeRatio" should be equal to the 474 * value from pseudo command line after VM Option file 475 */ 476 pb = prepareTestCase(2); 477 478 runJavaCheckExitValue(pb, JVM_SUCCESS); 479 480 outputShouldContain("interpreted mode"); 481 outputShouldNotContain("VM option '+PrintVMOptions'"); 482 checkProperty("shared.property", "command_line_after"); 483 checkVMOption("MinHeapFreeRatio", "9"); 484 485 /* 486 * The same as previous but without arguments in pseudo command line after 487 * VM Option file. 488 * "shared.property" property and "MinHeapFreeRatio" should be equal to the 489 * value from VM Option file. 490 */ 491 pb = prepareTestCase(3); 492 493 runJavaCheckExitValue(pb, JVM_SUCCESS); 494 495 outputShouldContain("interpreted mode"); 496 outputShouldContain("VM option '+PrintVMOptions'"); 497 checkProperty("shared.property", "vmoptfile"); 498 checkVMOption("MinHeapFreeRatio", "22"); 499 500 /* 501 * The same as previous but without arguments in VM Option file. 502 * "shared.property" property and "MinHeapFreeRatio" should be equal to the 503 * value from pseudo command line. 504 */ 505 pb = prepareTestCase(4); 506 507 runJavaCheckExitValue(pb, JVM_SUCCESS); 508 509 outputShouldNotContain("VM option '+PrintVMOptions'"); 510 checkProperty("shared.property", "command_line_before"); 511 checkVMOption("MinHeapFreeRatio", "7"); 512 513 /* 514 * The same as previous but without arguments from pseudo command line. 515 * "shared.property" property and "MinHeapFreeRatio" should be equal to the 516 * value from JAVA_TOOL_OPTIONS environment variable. 517 */ 518 pb = prepareTestCase(5); 519 520 runJavaCheckExitValue(pb, JVM_SUCCESS); 521 522 outputShouldContain("VM option '+PrintVMOptions'"); 523 checkProperty("shared.property", "java_tool_options"); 524 checkVMOption("MinHeapFreeRatio", "6"); 525 } 526 527 private static void testVMOptionsInvalid() throws Exception { 528 ProcessBuilder pb; 529 530 /* Pass directory instead of file */ 531 addVMOptionsFile(CURRENT_DIR); 532 533 runJavaCheckExitValue(JVM_FAIL_WITH_EXIT_CODE_1); 534 535 /* Pass not existing file */ 536 addVMOptionsFile(getAbsolutePathFromSource(NOT_EXISTING_FILE)); 537 538 runJavaCheckExitValue(JVM_FAIL_WITH_EXIT_CODE_1); 539 outputShouldContain("Could not open options file"); 540 541 /* Pass VM option file with bad option */ 542 addVMOptionsFile(getAbsolutePathFromSource(VM_OPTION_FILE_WITH_BAD_OPTION)); 543 544 runJavaCheckExitValue(JVM_FAIL_WITH_EXIT_CODE_1); 545 outputShouldContain("Unrecognized VM option"); 546 547 /* Pass VM option file with same VM option file option in it */ 548 addVMOptionsFile(VM_OPTION_FILE_WITH_SAME_VM_OPTION_FILE); 549 550 runJavaCheckExitValue(JVM_FAIL_WITH_EXIT_CODE_1); 551 outputShouldContain("The VM Options file can only be specified once and only on the command line."); 552 553 /* Pass VM option file with VM option file option in it */ 554 addVMOptionsFile(VM_OPTION_FILE_WITH_VM_OPTION_FILE); 555 556 runJavaCheckExitValue(JVM_FAIL_WITH_EXIT_CODE_1); 557 outputShouldContain("The VM Options file can only be specified once and only on the command line."); 558 559 /* Pass VM option file which is not accessible (without read permissions) */ 560 addVMOptionsFile(getAbsolutePathFromSource(VM_OPTION_FILE_WITHOUT_READ_PERMISSIONS)); 561 562 runJavaCheckExitValue(JVM_FAIL_WITH_EXIT_CODE_1); 563 outputShouldContain("Could not open options file"); 564 565 /* Pass two VM option files */ 566 addVMOptionsFile(getAbsolutePathFromSource(VM_OPTION_FILE_1)); 567 addVMOptionsFile(VM_OPTION_FILE_2); 568 569 runJavaCheckExitValue(JVM_FAIL_WITH_EXIT_CODE_1); 570 outputShouldContain("The VM Options file can only be specified once and only on the command line."); 571 572 /* Pass empty option file i.e. pass "-XX:VMOptionsFile=" */ 573 addVMOptionsFile(""); 574 575 runJavaCheckExitValue(JVM_FAIL_WITH_EXIT_CODE_1); 576 outputShouldContain("Could not open options file"); 577 578 /* Pass VM option file with unmatched single quote */ 579 addVMOptionsFile(getAbsolutePathFromSource(VM_OPTION_FILE_UNMATCHED_QUOTE_1)); 580 581 runJavaCheckExitValue(JVM_FAIL_WITH_EXIT_CODE_1); 582 outputShouldContain("Unmatched quote in"); 583 584 /* Pass VM option file with unmatched double quote in X option */ 585 addVMOptionsFile(getAbsolutePathFromSource(VM_OPTION_FILE_UNMATCHED_QUOTE_2)); 586 587 runJavaCheckExitValue(JVM_FAIL_WITH_EXIT_CODE_1); 588 outputShouldContain("Unmatched quote in"); 589 590 /* Pass VM Option file in _JAVA_OPTIONS environment variable */ 591 pb = createProcessBuilder(); 592 593 updateEnvironment(pb, JAVA_OPTIONS, "-XX:VMOptionsFile=" + getAbsolutePathFromSource(VM_OPTION_FILE_1)); 594 595 runJavaCheckExitValue(pb, JVM_FAIL_WITH_EXIT_CODE_1); 596 outputShouldContain("VM options file is only supported on the command line"); 597 598 /* Pass VM Option file in JAVA_TOOL_OPTIONS environment variable */ 599 pb = createProcessBuilder(); 600 601 updateEnvironment(pb, JAVA_TOOL_OPTIONS, "-XX:VMOptionsFile=" + getAbsolutePathFromSource(VM_OPTION_FILE_1)); 602 603 runJavaCheckExitValue(pb, JVM_FAIL_WITH_EXIT_CODE_1); 604 outputShouldContain("VM options file is only supported on the command line"); 605 } 606 607 public static void main(String[] args) throws Exception { 608 /* 609 * Preparation before actual testing - create two VM Option files 610 * which contains VM Option file in it and copy other files to the 611 * current working folder 612 */ 613 createOptionFiles(); 614 615 testVMOptions(); /* Test VM Option file general functionality */ 616 testVMOptionsLastArgumentsWins(); /* Verify that last argument wins */ 617 testVMOptionsInvalid(); /* Test invalid VM Option file functionality */ 618 619 } 620 621 public static class PrintPropertyAndOptions { 622 623 public static void main(String[] arguments) { 624 String vmOption; 625 Properties properties = System.getProperties(); 626 627 for (String propertyName : properties.stringPropertyNames()) { 628 System.out.println(String.format(PRINT_PROPERTY_FORMAT, propertyName, System.getProperty(propertyName, "NOT DEFINED"))); 629 } 630 631 for (String arg : arguments) { 632 if (arg.startsWith("vmoption=")) { 633 vmOption = arg.substring(9); 634 System.out.println(String.format(PRINT_VM_OPTION_FORMAT, vmOption, new DynamicVMOption(vmOption).getValue())); 635 } 636 } 637 } 638 } 639 }