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 8027634 8231863 27 * @summary Argument parsing from file 28 * @modules jdk.compiler 29 * jdk.zipfs 30 * @build TestHelper 31 * @run main ArgsFileTest 32 */ 33 import java.io.File; 34 import java.io.IOException; 35 import java.util.ArrayList; 36 import java.util.Arrays; 37 import java.util.Collections; 38 import java.util.HashMap; 39 import java.util.List; 40 import java.util.Map; 41 import java.util.regex.Matcher; 42 import java.util.regex.Pattern; 43 44 public class ArgsFileTest extends TestHelper { 45 private static File testJar = null; 46 private static Map<String, String> env = new HashMap<>(); 47 init()48 static void init() throws IOException { 49 if (testJar != null) { 50 return; 51 } 52 testJar = new File("test.jar"); 53 StringBuilder tsrc = new StringBuilder(); 54 tsrc.append("public static void main(String... args) {\n"); 55 tsrc.append(" for (String x : args) {\n"); 56 tsrc.append(" System.out.println(x);\n"); 57 tsrc.append(" }\n"); 58 tsrc.append("}\n"); 59 createJar(testJar, new File("Foo"), tsrc.toString()); 60 61 env.put(JLDEBUG_KEY, "true"); 62 } 63 createArgFile(String fname, List<String> lines, boolean endWithNewline)64 private File createArgFile(String fname, List<String> lines, boolean endWithNewline) throws IOException { 65 File argFile = new File(fname); 66 argFile.delete(); 67 createAFile(argFile, lines, endWithNewline); 68 return argFile; 69 } 70 createArgFile(String fname, List<String> lines)71 private File createArgFile(String fname, List<String> lines) throws IOException { 72 return createArgFile(fname, lines, true); 73 } 74 verifyOptions(List<String> args, TestResult tr)75 private void verifyOptions(List<String> args, TestResult tr) { 76 if (args.isEmpty()) { 77 return; 78 } 79 80 int i = 1; 81 for (String x : args) { 82 tr.matches(".*argv\\[" + i + "\\] = " + Pattern.quote(x) + ".*"); 83 i++; 84 } 85 if (! tr.testStatus) { 86 System.out.println(tr); 87 throw new RuntimeException("test fails"); 88 } 89 } 90 verifyUserArgs(List<String> args, TestResult tr, int index)91 private void verifyUserArgs(List<String> args, TestResult tr, int index) { 92 if (javaCmd != TestHelper.javaCmd) { 93 tr.contains("\tFirst application arg index: 1"); 94 } else { 95 tr.contains("\tFirst application arg index: " + index); 96 97 for (String arg: args) { 98 tr.matches("^" + Pattern.quote(arg) + "$"); 99 } 100 } 101 102 if (! tr.testStatus) { 103 System.out.println(tr); 104 throw new RuntimeException("test fails"); 105 } 106 } 107 108 @Test expandAll()109 public void expandAll() throws IOException { 110 List<String> lines = new ArrayList<>(); 111 lines.add("-Xmx32m"); 112 lines.add("-Xint"); 113 File argFile1 = createArgFile("argFile1", lines); 114 lines = new ArrayList<>(); 115 lines.add("-jar"); 116 lines.add("test.jar"); 117 lines.add("uarg1 @uarg2 @@uarg3 -uarg4 uarg5"); 118 File argFile2 = createArgFile("argFile2", lines); 119 120 TestResult tr = doExec(env, javaCmd, "@argFile1", "@argFile2"); 121 122 List<String> appArgs = new ArrayList<>(); 123 appArgs.add("uarg1"); 124 appArgs.add("@uarg2"); 125 appArgs.add("@@uarg3"); 126 appArgs.add("-uarg4"); 127 appArgs.add("uarg5"); 128 129 List<String> options = new ArrayList<>(); 130 options.add("-Xmx32m"); 131 options.add("-Xint"); 132 options.add("-jar"); 133 options.add("test.jar"); 134 options.addAll(appArgs); 135 136 verifyOptions(options, tr); 137 verifyUserArgs(appArgs, tr, 5); 138 argFile1.delete(); 139 argFile2.delete(); 140 141 File cpFile = createArgFile("cpFile", Arrays.asList("-cp", "test.jar")); 142 List<String> appCmd = new ArrayList<>(); 143 appCmd.add("Foo"); 144 appCmd.addAll(appArgs); 145 File appFile = createArgFile("appFile", appCmd); 146 147 tr = doExec(env, javaCmd, "@cpFile", "@appFile"); 148 verifyOptions(Arrays.asList("-cp", "test.jar", "Foo", 149 "uarg1", "@uarg2", "@@uarg3", "-uarg4", "uarg5"), tr); 150 verifyUserArgs(appArgs, tr, 4); 151 cpFile.delete(); 152 appFile.delete(); 153 } 154 155 @Test escapeArg()156 public void escapeArg() throws IOException { 157 List<String> lines = new ArrayList<>(); 158 lines.add("-Xmx32m"); 159 lines.add("-Xint"); 160 File argFile1 = createArgFile("argFile1", lines); 161 162 TestResult tr = doExec(env, javaCmd, "-cp", "@@arg", "-cp", "@", 163 "-cp", "@@@cp", "@argFile1", "@@@@Main@@@@", "-version"); 164 List<String> options = new ArrayList<>(); 165 options.add("-cp"); 166 options.add("@arg"); 167 options.add("-cp"); 168 options.add("@"); 169 options.add("-cp"); 170 options.add("@@cp"); 171 options.add("-Xmx32m"); 172 options.add("-Xint"); 173 options.add("@@@Main@@@@"); 174 options.add("-version"); 175 verifyOptions(options, tr); 176 verifyUserArgs(Collections.emptyList(), tr, options.size()); 177 argFile1.delete(); 178 } 179 180 @Test killSwitch()181 public void killSwitch() throws IOException { 182 List<String> lines = new ArrayList<>(); 183 lines.add("-Xmx32m"); 184 lines.add("-Xint"); 185 File argFile1 = createArgFile("argFile1", lines); 186 lines = new ArrayList<>(); 187 lines.add("-jar"); 188 lines.add("test.jar"); 189 lines.add("uarg1 @uarg2 @@uarg3 -uarg4 uarg5"); 190 File argFile2 = createArgFile("argFile2", lines); 191 File argKill = createArgFile("argKill", 192 Collections.singletonList("--disable-@files")); 193 194 TestResult tr = doExec(env, javaCmd, "@argFile1", "--disable-@files", "@argFile2"); 195 List<String> options = new ArrayList<>(); 196 options.add("-Xmx32m"); 197 options.add("-Xint"); 198 options.add("--disable-@files"); 199 options.add("@argFile2"); 200 verifyOptions(options, tr); 201 // Main class is @argFile2 202 verifyUserArgs(Collections.emptyList(), tr, 5); 203 204 // Specify in file is same as specify inline 205 tr = doExec(env, javaCmd, "@argFile1", "@argKill", "@argFile2"); 206 verifyOptions(options, tr); 207 // Main class is @argFile2 208 verifyUserArgs(Collections.emptyList(), tr, 5); 209 210 // multiple is fine, once on is on. 211 tr = doExec(env, javaCmd, "@argKill", "@argFile1", "--disable-@files", "@argFile2"); 212 options = Arrays.asList("--disable-@files", "@argFile1", 213 "--disable-@files", "@argFile2"); 214 verifyOptions(options, tr); 215 verifyUserArgs(Collections.emptyList(), tr, 3); 216 217 // after main class, becoming an user application argument 218 tr = doExec(env, javaCmd, "@argFile2", "@argKill"); 219 options = Arrays.asList("-jar", "test.jar", "uarg1", "@uarg2", "@@uarg3", 220 "-uarg4", "uarg5", "@argKill"); 221 verifyOptions(options, tr); 222 verifyUserArgs(Arrays.asList("uarg1", "@uarg2", "@@uarg3", 223 "-uarg4", "uarg5", "@argKill"), tr, 3); 224 225 argFile1.delete(); 226 argFile2.delete(); 227 argKill.delete(); 228 } 229 230 @Test userApplication()231 public void userApplication() throws IOException { 232 List<String> lines = new ArrayList<>(); 233 lines.add("-Xmx32m"); 234 lines.add("-Xint"); 235 File vmArgs = createArgFile("vmArgs", lines); 236 File jarOpt = createArgFile("jarOpt", Arrays.asList("-jar")); 237 File cpOpt = createArgFile("cpOpt", Arrays.asList("-cp")); 238 File jarArg = createArgFile("jarArg", Arrays.asList("test.jar")); 239 File userArgs = createArgFile("userArgs", Arrays.asList("-opt", "arg", "--longopt")); 240 241 TestResult tr = doExec(env, javaCmd, 242 "@vmArgs", "@jarOpt", "test.jar", "-opt", "arg", "--longopt"); 243 verifyOptions(Arrays.asList( 244 "-Xmx32m", "-Xint", "-jar", "test.jar", "-opt", "arg", "--longopt"), tr); 245 verifyUserArgs(Arrays.asList("-opt", "arg", "--longopt"), tr, 5); 246 247 tr = doExec(env, javaCmd, "@jarOpt", "@jarArg", "@vmArgs"); 248 verifyOptions(Arrays.asList("-jar", "test.jar", "@vmArgs"), tr); 249 verifyUserArgs(Arrays.asList("@vmArgs"), tr, 3); 250 251 tr = doExec(env, javaCmd, "-cp", "@jarArg", "@vmArgs", "Foo", "@userArgs"); 252 verifyOptions(Arrays.asList("-cp", "test.jar", "-Xmx32m", "-Xint", 253 "Foo", "@userArgs"), tr); 254 verifyUserArgs(Arrays.asList("@userArgs"), tr, 6); 255 256 tr = doExec(env, javaCmd, "@cpOpt", "@jarArg", "@vmArgs", "Foo", "@userArgs"); 257 verifyOptions(Arrays.asList("-cp", "test.jar", "-Xmx32m", "-Xint", 258 "Foo", "@userArgs"), tr); 259 verifyUserArgs(Arrays.asList("@userArgs"), tr, 6); 260 261 tr = doExec(env, javaCmd, "@cpOpt", "test.jar", "@vmArgs", "Foo", "@userArgs"); 262 verifyOptions(Arrays.asList("-cp", "test.jar", "-Xmx32m", "-Xint", 263 "Foo", "@userArgs"), tr); 264 verifyUserArgs(Arrays.asList("@userArgs"), tr, 6); 265 266 vmArgs.delete(); 267 jarOpt.delete(); 268 cpOpt.delete(); 269 jarArg.delete(); 270 userArgs.delete(); 271 } 272 273 @Test userApplicationWithoutEmptyLastLine()274 public void userApplicationWithoutEmptyLastLine() throws IOException { 275 File cpOpt = createArgFile("cpOpt", Arrays.asList("-classpath ."), false); 276 File vmArgs = createArgFile("vmArgs", Arrays.asList("-Xint"), false); 277 278 TestResult tr = doExec(env, javaCmd, "-cp", "test.jar", "@cpOpt", "Foo", "-test"); 279 verifyOptions(Arrays.asList("-cp", "test.jar", "-classpath", ".", "Foo", "-test"), tr); 280 verifyUserArgs(Arrays.asList("-test"), tr, 6); 281 282 tr = doExec(env, javaCmd, "-cp", "test.jar", "@vmArgs", "Foo", "-test"); 283 verifyOptions(Arrays.asList("-cp", "test.jar", "-Xint", "Foo", "-test"), tr); 284 verifyUserArgs(Arrays.asList("-test"), tr, 5); 285 286 cpOpt.delete(); 287 vmArgs.delete(); 288 } 289 290 // test with missing file 291 @Test missingFileNegativeTest()292 public void missingFileNegativeTest() throws IOException { 293 TestResult tr = doExec(javaCmd, "@" + "missing.cmd"); 294 tr.checkNegative(); 295 tr.contains("Error: could not open `missing.cmd'"); 296 if (!tr.testStatus) { 297 System.out.println(tr); 298 throw new RuntimeException("test fails"); 299 } 300 } 301 main(String... args)302 public static void main(String... args) throws Exception { 303 init(); 304 ArgsFileTest a = new ArgsFileTest(); 305 a.run(args); 306 if (testExitValue > 0) { 307 System.out.println("Total of " + testExitValue + " failed"); 308 System.exit(1); 309 } else { 310 System.out.println("All tests pass"); 311 } 312 } 313 } 314