1 /* 2 * Copyright (c) 2017, 2018, 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 8192920 27 * @summary Test source mode 28 * @modules jdk.compiler 29 * @run main SourceMode 30 */ 31 32 33 import java.io.IOException; 34 import java.nio.file.Files; 35 import java.nio.file.Path; 36 import java.nio.file.Paths; 37 import java.nio.file.attribute.PosixFilePermission; 38 import java.util.ArrayList; 39 import java.util.Arrays; 40 import java.util.HashMap; 41 import java.util.List; 42 import java.util.Map; 43 import java.util.Set; 44 45 public class SourceMode extends TestHelper { 46 47 public static void main(String... args) throws Exception { 48 new SourceMode().run(args); 49 } 50 51 // java Simple.java 1 2 3 52 @Test 53 void testSimpleJava() throws IOException { 54 Path file = getSimpleFile("Simple.java", false); 55 TestResult tr = doExec(javaCmd, file.toString(), "1", "2", "3"); 56 if (!tr.isOK()) 57 error(tr, "Bad exit code: " + tr.exitValue); 58 if (!tr.contains("[1, 2, 3]")) 59 error(tr, "Expected output not found"); 60 System.out.println(tr.testOutput); 61 } 62 63 // java --source 10 simple 1 2 3 64 @Test 65 void testSimple() throws IOException { 66 Path file = getSimpleFile("simple", false); 67 TestResult tr = doExec(javaCmd, "--source", "10", file.toString(), "1", "2", "3"); 68 if (!tr.isOK()) 69 error(tr, "Bad exit code: " + tr.exitValue); 70 if (!tr.contains("[1, 2, 3]")) 71 error(tr, "Expected output not found"); 72 System.out.println(tr.testOutput); 73 } 74 75 // execSimple 1 2 3 76 @Test 77 void testExecSimple() throws IOException { 78 if (isWindows) // Will not work without cygwin, pass silently 79 return; 80 Path file = setExecutable(getSimpleFile("execSimple", true)); 81 TestResult tr = doExec(file.toAbsolutePath().toString(), "1", "2", "3"); 82 if (!tr.isOK()) 83 error(tr, "Bad exit code: " + tr.exitValue); 84 if (!tr.contains("[1, 2, 3]")) 85 error(tr, "Expected output not found"); 86 System.out.println(tr.testOutput); 87 } 88 89 // java @simpleJava.at (contains Simple.java 1 2 3) 90 @Test 91 void testSimpleJavaAtFile() throws IOException { 92 Path file = getSimpleFile("Simple.java", false); 93 Path atFile = Paths.get("simpleJava.at"); 94 createFile(atFile.toFile(), List.of(file + " 1 2 3")); 95 TestResult tr = doExec(javaCmd, "@" + atFile); 96 if (!tr.isOK()) 97 error(tr, "Bad exit code: " + tr.exitValue); 98 if (!tr.contains("[1, 2, 3]")) 99 error(tr, "Expected output not found"); 100 System.out.println(tr.testOutput); 101 } 102 103 // java @simple.at (contains --source 10 simple 1 2 3) 104 @Test 105 void testSimpleAtFile() throws IOException { 106 Path file = getSimpleFile("simple", false); 107 Path atFile = Paths.get("simple.at"); 108 createFile(atFile.toFile(), List.of("--source 10 " + file + " 1 2 3")); 109 TestResult tr = doExec(javaCmd, "@" + atFile); 110 if (!tr.isOK()) 111 error(tr, "Bad exit code: " + tr.exitValue); 112 if (!tr.contains("[1, 2, 3]")) 113 error(tr, "Expected output not found"); 114 System.out.println(tr.testOutput); 115 } 116 117 // java -cp classes Main.java 1 2 3 118 @Test 119 void testClasspath() throws IOException { 120 Path base = Files.createDirectories(Paths.get("testClasspath")); 121 Path otherJava = base.resolve("Other.java"); 122 createFile(otherJava.toFile(), List.of( 123 "public class Other {", 124 " public static String join(String[] args) {", 125 " return String.join(\"-\", args);", 126 " }", 127 "}" 128 )); 129 Path classes = Files.createDirectories(base.resolve("classes")); 130 Path mainJava = base.resolve("Main.java"); 131 createFile(mainJava.toFile(), List.of( 132 "class Main {", 133 " public static void main(String[] args) {", 134 " System.out.println(Other.join(args));", 135 " }}" 136 )); 137 compile("-d", classes.toString(), otherJava.toString()); 138 TestResult tr = doExec(javaCmd, "-cp", classes.toString(), 139 mainJava.toString(), "1", "2", "3"); 140 if (!tr.isOK()) 141 error(tr, "Bad exit code: " + tr.exitValue); 142 if (!tr.contains("1-2-3")) 143 error(tr, "Expected output not found"); 144 System.out.println(tr.testOutput); 145 } 146 147 // java --add-exports=... Export.java --help 148 @Test 149 void testAddExports() throws IOException { 150 Path exportJava = Paths.get("Export.java"); 151 createFile(exportJava.toFile(), List.of( 152 "public class Export {", 153 " public static void main(String[] args) {", 154 " new com.sun.tools.javac.main.Main(\"demo\").compile(args);", 155 " }", 156 "}" 157 )); 158 // verify access fails without --add-exports 159 TestResult tr1 = doExec(javaCmd, exportJava.toString(), "--help"); 160 if (tr1.isOK()) 161 error(tr1, "Compilation succeeded unexpectedly"); 162 // verify access succeeds with --add-exports 163 TestResult tr2 = doExec(javaCmd, 164 "--add-exports", "jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED", 165 exportJava.toString(), "--help"); 166 if (!tr2.isOK()) 167 error(tr2, "Bad exit code: " + tr2.exitValue); 168 if (!(tr2.contains("demo") && tr2.contains("Usage"))) 169 error(tr2, "Expected output not found"); 170 } 171 172 // java -cp ... HelloWorld.java (for a class "java" in package "HelloWorld") 173 @Test 174 void testClassNamedJava() throws IOException { 175 Path base = Files.createDirectories(Paths.get("testClassNamedJava")); 176 Path src = Files.createDirectories(base.resolve("src")); 177 Path srcfile = src.resolve("java.java"); 178 createFile(srcfile.toFile(), List.of( 179 "package HelloWorld;", 180 "class java {", 181 " public static void main(String... args) {", 182 " System.out.println(HelloWorld.java.class.getName());", 183 " }", 184 "}" 185 )); 186 Path classes = base.resolve("classes"); 187 compile("-d", classes.toString(), srcfile.toString()); 188 TestResult tr = 189 doExec(javaCmd, "-cp", classes.toString(), "HelloWorld.java"); 190 if (!tr.isOK()) 191 error(tr, "Command failed"); 192 if (!tr.contains("HelloWorld.java")) 193 error(tr, "Expected output not found"); 194 } 195 196 // java --source 197 @Test 198 void testSourceNoArg() throws IOException { 199 TestResult tr = doExec(javaCmd, "--source"); 200 if (tr.isOK()) 201 error(tr, "Command succeeded unexpectedly"); 202 System.err.println(tr); 203 if (!tr.contains("--source requires source version")) 204 error(tr, "Expected output not found"); 205 } 206 207 // java --source 10 -jar simple.jar 208 @Test 209 void testSourceJarConflict() throws IOException { 210 Path base = Files.createDirectories(Paths.get("testSourceJarConflict")); 211 Path file = getSimpleFile("Simple.java", false); 212 Path classes = Files.createDirectories(base.resolve("classes")); 213 compile("-d", classes.toString(), file.toString()); 214 Path simpleJar = base.resolve("simple.jar"); 215 createJar("cf", simpleJar.toString(), "-C", classes.toString(), "."); 216 TestResult tr = 217 doExec(javaCmd, "--source", "10", "-jar", simpleJar.toString()); 218 if (tr.isOK()) 219 error(tr, "Command succeeded unexpectedly"); 220 if (!tr.contains("Option -jar is not allowed with --source")) 221 error(tr, "Expected output not found"); 222 } 223 224 // java --source 10 -m jdk.compiler 225 @Test 226 void testSourceModuleConflict() throws IOException { 227 TestResult tr = doExec(javaCmd, "--source", "10", "-m", "jdk.compiler"); 228 if (tr.isOK()) 229 error(tr, "Command succeeded unexpectedly"); 230 if (!tr.contains("Option -m is not allowed with --source")) 231 error(tr, "Expected output not found"); 232 } 233 234 // #!.../java --source 10 -version 235 @Test 236 void testTerminalOptionInShebang() throws IOException { 237 if (isWindows) // Will not work without cygwin, pass silently 238 return; 239 Path base = Files.createDirectories( 240 Paths.get("testTerminalOptionInShebang")); 241 Path bad = base.resolve("bad"); 242 createFile(bad.toFile(), List.of( 243 "#!" + javaCmd + " --source 10 -version")); 244 setExecutable(bad); 245 TestResult tr = doExec(bad.toString()); 246 if (!tr.contains("Option -version is not allowed in this context")) 247 error(tr, "Expected output not found"); 248 } 249 250 // #!.../java --source 10 @bad.at (contains -version) 251 @Test 252 void testTerminalOptionInShebangAtFile() throws IOException { 253 if (isWindows) // Will not work without cygwin, pass silently 254 return; 255 // Use a short directory name, to avoid line length limitations 256 Path base = Files.createDirectories(Paths.get("testBadAtFile")); 257 Path bad_at = base.resolve("bad.at"); 258 createFile(bad_at.toFile(), List.of("-version")); 259 Path bad = base.resolve("bad"); 260 createFile(bad.toFile(), List.of( 261 "#!" + javaCmd + " --source 10 @" + bad_at)); 262 setExecutable(bad); 263 TestResult tr = doExec(bad.toString()); 264 System.err.println("JJG JJG " + tr); 265 if (!tr.contains("Option -version in @testBadAtFile/bad.at is " 266 + "not allowed in this context")) 267 error(tr, "Expected output not found"); 268 } 269 270 // #!.../java --source 10 HelloWorld 271 @Test 272 void testMainClassInShebang() throws IOException { 273 if (isWindows) // Will not work without cygwin, pass silently 274 return; 275 Path base = Files.createDirectories(Paths.get("testMainClassInShebang")); 276 Path bad = base.resolve("bad"); 277 createFile(bad.toFile(), List.of( 278 "#!" + javaCmd + " --source 10 HelloWorld")); 279 setExecutable(bad); 280 TestResult tr = doExec(bad.toString()); 281 if (!tr.contains("Cannot specify main class in this context")) 282 error(tr, "Expected output not found"); 283 } 284 285 //-------------------------------------------------------------------------- 286 287 private Map<String,String> getLauncherDebugEnv() { 288 return Map.of("_JAVA_LAUNCHER_DEBUG", "1"); 289 } 290 291 private Path getSimpleFile(String name, boolean shebang) throws IOException { 292 Path file = Paths.get(name); 293 if (!Files.exists(file)) { 294 createFile(file.toFile(), List.of( 295 (shebang ? "#!" + javaCmd + " --source 10" : ""), 296 "public class Simple {", 297 " public static void main(String[] args) {", 298 " System.out.println(java.util.Arrays.toString(args));", 299 " }}")); 300 } 301 return file; 302 } 303 304 private Path setExecutable(Path file) throws IOException { 305 Set<PosixFilePermission> perms = Files.getPosixFilePermissions(file); 306 perms.add(PosixFilePermission.OWNER_EXECUTE); 307 Files.setPosixFilePermissions(file, perms); 308 return file; 309 } 310 311 private void error(TestResult tr, String message) { 312 System.err.println(tr); 313 throw new RuntimeException(message); 314 } 315 }