1 /* 2 * Copyright (c) 2014, 2017, 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 4981566 5028634 5094412 6304984 7025786 7025789 8001112 8028545 8000961 8030610 8028546 8188870 8173382 27 * @summary Check interpretation of -target and -source options 28 * @modules java.compiler 29 * jdk.compiler 30 * @run main Versions 31 */ 32 33 import java.io.*; 34 import java.nio.*; 35 import java.nio.channels.*; 36 37 import javax.tools.JavaCompiler; 38 import javax.tools.ToolProvider; 39 import javax.tools.JavaFileObject; 40 import javax.tools.StandardJavaFileManager; 41 import java.util.List; 42 import java.util.ArrayList; 43 import java.util.Arrays; 44 45 46 public class Versions { 47 48 protected JavaCompiler javacompiler; 49 protected int failedCases; 50 51 public Versions() throws IOException { 52 javacompiler = ToolProvider.getSystemJavaCompiler(); 53 genSourceFiles(); 54 failedCases = 0; 55 } 56 57 public static void main(String... args) throws IOException { 58 Versions versions = new Versions(); 59 versions.run(); 60 } 61 62 void run() { 63 64 String TC = ""; 65 System.out.println("Version.java: Starting"); 66 67 check("54.0"); 68 check("54.0", "-source 1.6"); 69 check("54.0", "-source 1.7"); 70 check("54.0", "-source 1.8"); 71 check("54.0", "-source 1.9"); 72 check("54.0", "-source 1.10"); 73 check("54.0", "-source 11"); 74 75 check_source_target(true, "50.0", "6", "6"); 76 check_source_target(true, "51.0", "6", "7"); 77 check_source_target(true, "51.0", "7", "7"); 78 check_source_target(true, "52.0", "6", "8"); 79 check_source_target(true, "52.0", "7", "8"); 80 check_source_target(true, "52.0", "8", "8"); 81 check_source_target(true, "53.0", "6", "9"); 82 check_source_target(true, "53.0", "7", "9"); 83 check_source_target(true, "53.0", "8", "9"); 84 check_source_target(true, "53.0", "9", "9"); 85 check_source_target(true, "54.0", "6", "10"); 86 check_source_target(true, "54.0", "7", "10"); 87 check_source_target(true, "54.0", "8", "10"); 88 check_source_target(true, "54.0", "9", "10"); 89 check_source_target(true, "54.0", "10", "10"); 90 check_source_target(false, "54.0", "11", "11"); 91 92 checksrc16("-source 1.6"); 93 checksrc16("-source 6"); 94 checksrc16("-source 1.6", "-target 1.6"); 95 checksrc16("-source 6", "-target 6"); 96 checksrc17("-source 1.7"); 97 checksrc17("-source 7"); 98 checksrc17("-source 1.7", "-target 1.7"); 99 checksrc17("-source 7", "-target 7"); 100 checksrc18("-source 1.8"); 101 checksrc18("-source 8"); 102 checksrc18("-source 1.8", "-target 1.8"); 103 checksrc18("-source 8", "-target 8"); 104 checksrc19("-source 1.9"); 105 checksrc19("-source 9"); 106 checksrc19("-source 1.9", "-target 1.9"); 107 checksrc19("-source 9", "-target 9"); 108 checksrc110(); 109 checksrc110("-source 1.10"); 110 checksrc110("-source 10"); 111 checksrc110("-source 1.10", "-target 1.10"); 112 checksrc110("-source 10", "-target 10"); 113 checksrc111("-source 11"); 114 checksrc111("-source 11", "-target 11"); 115 checksrc111("-target 11"); 116 117 fail("-source 7", "-target 1.6", "Base.java"); 118 fail("-source 8", "-target 1.6", "Base.java"); 119 fail("-source 8", "-target 1.7", "Base.java"); 120 fail("-source 9", "-target 1.7", "Base.java"); 121 fail("-source 9", "-target 1.8", "Base.java"); 122 fail("-source 10", "-target 1.7", "Base.java"); 123 fail("-source 10", "-target 1.8", "Base.java"); 124 fail("-source 11", "-target 1.9", "Base.java"); 125 fail("-source 11", "-target 1.10", "Base.java"); 126 127 fail("-source 1.5", "-target 1.5", "Base.java"); 128 fail("-source 1.4", "-target 1.4", "Base.java"); 129 fail("-source 1.3", "-target 1.3", "Base.java"); 130 fail("-source 1.2", "-target 1.2", "Base.java"); 131 132 if (failedCases > 0) { 133 System.err.println("failedCases = " + String.valueOf(failedCases)); 134 throw new Error("Test failed"); 135 } 136 137 } 138 139 protected void printargs(String fname,String... args) { 140 System.out.printf("test: %s", fname); 141 for (String onearg : args) { 142 System.out.printf(" %s", onearg); 143 } 144 System.out.printf("\n", fname); 145 } 146 147 protected void check_source_target(boolean dotOne, String... args) { 148 printargs("check_source_target", args); 149 check_target(dotOne, args[0], args[1], args[2]); 150 if (dotOne) { 151 check_target(dotOne, args[0], "1." + args[1], args[2]); 152 } 153 } 154 155 protected void check_target(boolean dotOne, String... args) { 156 check(args[0], "-source " + args[1], "-target " + args[2]); 157 if (dotOne) { 158 check(args[0], "-source " + args[1], "-target 1." + args[2]); 159 } 160 } 161 162 protected void check(String major, String... args) { 163 printargs("check", args); 164 List<String> jcargs = new ArrayList<>(); 165 jcargs.add("-Xlint:-options"); 166 167 // add in args conforming to List requrements of JavaCompiler 168 for (String onearg : args) { 169 String[] fields = onearg.split(" "); 170 for (String onefield : fields) { 171 jcargs.add(onefield); 172 } 173 } 174 175 boolean creturn = compile("Base.java", jcargs); 176 if (!creturn) { 177 // compilation errors note and return.. assume no class file 178 System.err.println("check: Compilation Failed"); 179 System.err.println("\t classVersion:\t" + major); 180 System.err.println("\t arguments:\t" + jcargs); 181 failedCases++; 182 183 } else if (!checkClassFileVersion("Base.class", major)) { 184 failedCases++; 185 } 186 } 187 188 protected void checksrc16(String... args) { 189 printargs("checksrc16", args); 190 int asize = args.length; 191 String[] newargs = new String[asize + 1]; 192 System.arraycopy(args, 0, newargs, 0, asize); 193 newargs[asize] = "Base.java"; 194 pass(newargs); 195 newargs[asize] = "New17.java"; 196 fail(newargs); 197 } 198 199 protected void checksrc17(String... args) { 200 printargs("checksrc17", args); 201 int asize = args.length; 202 String[] newargs = new String[asize+1]; 203 System.arraycopy(args, 0, newargs,0 , asize); 204 newargs[asize] = "New17.java"; 205 pass(newargs); 206 newargs[asize] = "New18.java"; 207 fail(newargs); 208 } 209 210 protected void checksrc18(String... args) { 211 printargs("checksrc18", args); 212 int asize = args.length; 213 String[] newargs = new String[asize+1]; 214 System.arraycopy(args, 0, newargs,0 , asize); 215 newargs[asize] = "New17.java"; 216 pass(newargs); 217 newargs[asize] = "New18.java"; 218 pass(newargs); 219 newargs[asize] = "New110.java"; 220 fail(newargs); 221 } 222 223 protected void checksrc19(String... args) { 224 printargs("checksrc19", args); 225 checksrc18(args); 226 } 227 228 protected void checksrc110(String... args) { 229 printargs("checksrc110", args); 230 int asize = args.length; 231 String[] newargs = new String[asize+1]; 232 System.arraycopy(args, 0, newargs,0 , asize); 233 newargs[asize] = "New17.java"; 234 pass(newargs); 235 newargs[asize] = "New18.java"; 236 pass(newargs); 237 newargs[asize] = "New110.java"; 238 pass(newargs); 239 } 240 241 protected void checksrc111(String... args) { 242 printargs("checksrc111", args); 243 checksrc110(args); 244 } 245 246 protected void pass(String... args) { 247 printargs("pass", args); 248 249 List<String> jcargs = new ArrayList<String>(); 250 jcargs.add("-Xlint:-options"); 251 252 // add in args conforming to List requrements of JavaCompiler 253 for (String onearg : args) { 254 String[] fields = onearg.split(" "); 255 for (String onefield : fields) { 256 jcargs.add(onefield); 257 } 258 } 259 260 // empty list is error 261 if (jcargs.isEmpty()) { 262 System.err.println("error: test error in pass() - No arguments"); 263 System.err.println("\t arguments:\t" + jcargs); 264 failedCases++; 265 return; 266 } 267 268 // the last argument is the filename *.java 269 String filename = jcargs.get(jcargs.size() - 1); 270 jcargs.remove(jcargs.size() - 1); 271 272 boolean creturn = compile(filename, jcargs); 273 // expect a compilation failure, failure if otherwise 274 if (!creturn) { 275 System.err.println("pass: Compilation erroneously failed"); 276 System.err.println("\t arguments:\t" + jcargs); 277 System.err.println("\t file :\t" + filename); 278 failedCases++; 279 280 } 281 282 } 283 284 protected void fail(String... args) { 285 printargs("fail", args); 286 287 List<String> jcargs = new ArrayList<String>(); 288 jcargs.add("-Xlint:-options"); 289 290 // add in args conforming to List requrements of JavaCompiler 291 for (String onearg : args) { 292 String[] fields = onearg.split(" "); 293 for (String onefield : fields) { 294 jcargs.add(onefield); 295 } 296 } 297 298 // empty list is error 299 if (jcargs.isEmpty()) { 300 System.err.println("error: test error in fail()- No arguments"); 301 System.err.println("\t arguments:\t" + jcargs); 302 failedCases++; 303 return; 304 } 305 306 // the last argument is the filename *.java 307 String filename = jcargs.get(jcargs.size() - 1); 308 jcargs.remove(jcargs.size() - 1); 309 310 boolean creturn = compile(filename, jcargs); 311 // expect a compilation failure, failure if otherwise 312 if (creturn) { 313 System.err.println("fail: Compilation erroneously succeeded"); 314 System.err.println("\t arguments:\t" + jcargs); 315 System.err.println("\t file :\t" + filename); 316 failedCases++; 317 } 318 } 319 320 protected boolean compile(String sourceFile, List<String>options) { 321 JavaCompiler.CompilationTask jctask; 322 try (StandardJavaFileManager fm = javacompiler.getStandardFileManager(null, null, null)) { 323 Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(sourceFile); 324 325 jctask = javacompiler.getTask( 326 null, // Writer 327 fm, // JavaFileManager 328 null, // DiagnosticListener 329 options, // Iterable<String> 330 null, // Iterable<String> classes 331 files); // Iterable<? extends JavaFileObject> 332 333 try { 334 return jctask.call(); 335 } catch (IllegalStateException e) { 336 System.err.println(e); 337 return false; 338 } 339 } catch (IOException e) { 340 throw new Error(e); 341 } 342 } 343 344 protected void writeSourceFile(String fileName, String body) throws IOException{ 345 try (Writer fw = new FileWriter(fileName)) { 346 fw.write(body); 347 } 348 } 349 350 protected void genSourceFiles() throws IOException{ 351 /* Create a file that executes with all supported versions. */ 352 writeSourceFile("Base.java","public class Base { }\n"); 353 354 /* 355 * Create a file with a new feature in 1.7, not in 1.6 : "<>" 356 */ 357 writeSourceFile("New17.java", 358 "import java.util.List;\n" + 359 "import java.util.ArrayList;\n" + 360 "class New17 { List<String> s = new ArrayList<>(); }\n" 361 ); 362 363 /* 364 * Create a file with a new feature in 1.8, not in 1.7 : lambda 365 */ 366 writeSourceFile("New18.java", 367 "public class New18 { \n" + 368 " void m() { \n" + 369 " new Thread(() -> { }); \n" + 370 " } \n" + 371 "} \n" 372 ); 373 374 /* 375 * Create a file with a new feature in 1.10, not in 1.9 : var 376 */ 377 writeSourceFile("New110.java", 378 "public class New110 { \n" + 379 " void m() { \n" + 380 " var tmp = new Thread(() -> { }); \n" + 381 " } \n" + 382 "} \n" 383 ); 384 385 } 386 387 protected boolean checkClassFileVersion 388 (String filename,String classVersionNumber) { 389 ByteBuffer bb = ByteBuffer.allocate(1024); 390 try (FileChannel fc = new FileInputStream(filename).getChannel()) { 391 bb.clear(); 392 if (fc.read(bb) < 0) 393 throw new IOException("Could not read from file : " + filename); 394 bb.flip(); 395 int minor = bb.getShort(4); 396 int major = bb.getShort(6); 397 String fileVersion = major + "." + minor; 398 if (fileVersion.equals(classVersionNumber)) { 399 return true; 400 } else { 401 System.err.println("checkClassFileVersion : Failed"); 402 System.err.println("\tclassfile version mismatch"); 403 System.err.println("\texpected : " + classVersionNumber); 404 System.err.println("\tfound : " + fileVersion); 405 return false; 406 } 407 } 408 catch (IOException e) { 409 System.err.println("checkClassFileVersion : Failed"); 410 System.err.println("\terror :\t" + e.getMessage()); 411 System.err.println("\tfile:\tfilename"); 412 } 413 return false; 414 } 415 } 416