1 /* 2 * Copyright (c) 2010, 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 6999210 27 * @summary javac should be able to warn of anomalous conditions in classfiles 28 * @modules jdk.compiler 29 */ 30 31 import java.io.*; 32 import java.util.*; 33 34 public class T6999210 { main(String... args)35 public static void main(String... args) throws Exception { 36 new T6999210().run(); 37 } 38 run()39 void run() throws Exception { 40 File srcDir = new File("src"); 41 File classesDir = new File("classes"); 42 classesDir.mkdirs(); 43 44 File c_java = writeFile(srcDir, "C.java", "class C<T> { }"); 45 compile("-d", classesDir.getPath(), c_java.getPath()); 46 File c_class = new File(classesDir, "C.class"); 47 setMajorVersion(c_class, 48); 48 File d_java = writeFile(srcDir, "D.java", "class D { C c; }"); 49 50 // verify no warning if -Xlint:classfile not enabled 51 String out1 = compile( 52 "-d", classesDir.getPath(), 53 "-classpath", classesDir.getPath(), 54 d_java.getPath()); 55 if (out1.length() > 0) 56 error("unexpected output from javac"); 57 58 // sanity check of warning when -XDrawDiagnostics not used 59 String out2 = compile( 60 "-d", classesDir.getPath(), 61 "-classpath", classesDir.getPath(), 62 "-Xlint:classfile", 63 d_java.getPath()); 64 if (!out2.contains("[classfile]")) 65 error("expected output \"[classfile]\" not found"); 66 67 // check specific details, using -XDrawDiagnostics 68 String out3 = compile( 69 "-d", classesDir.getPath(), 70 "-classpath", classesDir.getPath(), 71 "-Xlint:classfile", "-XDrawDiagnostics", 72 d_java.getPath()); 73 String expect = "C.class:-:-: compiler.warn.future.attr: Signature, 49, 0, 48, 0"; 74 if (!out3.contains(expect)) 75 error("expected output \"" + expect + "\" not found"); 76 77 if (errors > 0) 78 throw new Exception(errors + " errors occurred"); 79 } 80 compile(String... args)81 String compile(String... args) throws Exception { 82 System.err.println("compile: " + Arrays.asList(args)); 83 StringWriter sw = new StringWriter(); 84 PrintWriter pw = new PrintWriter(sw); 85 int rc = com.sun.tools.javac.Main.compile(args, pw); 86 pw.close(); 87 String out = sw.toString(); 88 if (out.length() > 0) 89 System.err.println(out); 90 if (rc != 0) 91 throw new Exception("compilation failed, rc=" + rc); 92 return out; 93 } 94 setMajorVersion(File f, int major)95 void setMajorVersion(File f, int major) throws IOException { 96 int len = (int) f.length(); 97 byte[] data = new byte[len]; 98 try (DataInputStream in = new DataInputStream(new FileInputStream(f))) { 99 in.readFully(data); 100 } 101 // u4 magic 102 // u2 minor 103 data[6] = (byte) (major >> 8); 104 data[7] = (byte) (major & 0xff); 105 try (FileOutputStream out = new FileOutputStream(f)) { 106 out.write(data); 107 } 108 } 109 writeFile(File dir, String path, String body)110 File writeFile(File dir, String path, String body) throws IOException { 111 File f = new File(dir, path); 112 f.getParentFile().mkdirs(); 113 try (FileWriter out = new FileWriter(f)) { 114 out.write(body); 115 } 116 return f; 117 } 118 error(String msg)119 void error(String msg) { 120 System.err.println("Error: " + msg); 121 errors++; 122 } 123 124 int errors; 125 } 126