1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/test/tools/javac/4241573/T4241573.java Wed Apr 27 01:34:52 2016 +0800 1.3 @@ -0,0 +1,230 @@ 1.4 +/* 1.5 + * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + */ 1.26 + 1.27 +/* 1.28 + * @test 1.29 + * @bug 4241573 1.30 + * @summary SourceFile attribute includes full path 1.31 + */ 1.32 + 1.33 +import com.sun.tools.classfile.Attribute; 1.34 +import com.sun.tools.classfile.ClassFile; 1.35 +import com.sun.tools.classfile.SourceFile_attribute; 1.36 +import java.io.*; 1.37 +import java.util.*; 1.38 +import java.util.jar.*; 1.39 + 1.40 +public class T4241573 { 1.41 + public static void main(String... args) throws Exception { 1.42 + new T4241573().run(); 1.43 + } 1.44 + 1.45 + public void run() throws Exception { 1.46 + // Selection of files to be compiled 1.47 + File absJar = createJar(new File("abs.jar").getAbsoluteFile(), "j.A"); 1.48 + File relJar = createJar(new File("rel.jar"), "j.R"); 1.49 + File absDir = createDir(new File("abs.dir").getAbsoluteFile(), "d.A"); 1.50 + File relDir = createDir(new File("rel.dir"), "d.R"); 1.51 + File absTestFile = writeFile(new File("AbsTest.java").getAbsoluteFile(), "class AbsTest { class Inner { } }"); 1.52 + File relTestFile = writeFile(new File("RelTest.java"), "class RelTest { class Inner { } }"); 1.53 + File relTest2File = writeFile(new File("p/RelTest2.java"), "package p; class RelTest2 { class Inner { } }"); 1.54 + // This next class references other classes that will be found on the source path 1.55 + // and which will therefore need to be compiled as well. 1.56 + File mainFile = writeFile(new File("Main.java"), 1.57 + "class Main { j.A ja; j.R jr; d.A da; d.R dr; }" + 1.58 + ""); 1.59 + 1.60 + String sourcePath = createPath(absJar, relJar, absDir, relDir); 1.61 + File outDir = new File("classes"); 1.62 + outDir.mkdirs(); 1.63 + 1.64 + String[] args = { 1.65 + "-sourcepath", sourcePath, 1.66 + "-d", outDir.getPath(), 1.67 + absTestFile.getPath(), 1.68 + relTestFile.getPath(), 1.69 + relTest2File.getPath(), 1.70 + mainFile.getPath(), 1.71 + }; 1.72 + System.err.println("compile: " + Arrays.asList(args)); 1.73 + StringWriter sw = new StringWriter(); 1.74 + PrintWriter pw = new PrintWriter(sw); 1.75 + int rc = com.sun.tools.javac.Main.compile(args, pw); 1.76 + pw.close(); 1.77 + if (rc != 0) { 1.78 + System.err.println(sw.toString()); 1.79 + throw new Exception("unexpected exit from javac: " + rc); 1.80 + } 1.81 + 1.82 + Set<File> expect = getFiles(outDir, 1.83 + "d/A.class", "d/A$Inner.class", 1.84 + "d/R.class", "d/R$Inner.class", 1.85 + "j/A.class", "j/A$Inner.class", 1.86 + "j/R.class", "j/R$Inner.class", 1.87 + "AbsTest.class", "AbsTest$Inner.class", 1.88 + "RelTest.class", "RelTest$Inner.class", 1.89 + "p/RelTest2.class", "p/RelTest2$Inner.class", 1.90 + "Main.class" ); 1.91 + 1.92 + Set<File> found = findFiles(outDir); 1.93 + 1.94 + if (!found.equals(expect)) { 1.95 + if (found.containsAll(expect)) 1.96 + throw new Exception("unexpected files found: " + diff(found, expect)); 1.97 + else if (expect.containsAll(found)) 1.98 + throw new Exception("expected files not found: " + diff(expect, found)); 1.99 + } 1.100 + 1.101 + for (File f: found) 1.102 + verifySourceFileAttribute(f); 1.103 + 1.104 + if (errors > 0) 1.105 + throw new Exception(errors + " errors occurred"); 1.106 + } 1.107 + 1.108 + /** Check the SourceFileAttribute is the simple name of the original source file. */ 1.109 + void verifySourceFileAttribute(File f) { 1.110 + System.err.println("verify: " + f); 1.111 + try { 1.112 + ClassFile cf = ClassFile.read(f); 1.113 + SourceFile_attribute sfa = (SourceFile_attribute) cf.getAttribute(Attribute.SourceFile); 1.114 + String found = sfa.getSourceFile(cf.constant_pool); 1.115 + String expect = f.getName().replaceAll("([$.].*)?\\.class", ".java"); 1.116 + if (!expect.equals(found)) { 1.117 + error("bad value found: " + found + ", expected: " + expect); 1.118 + } 1.119 + } catch (Exception e) { 1.120 + error("error reading " + f +": " + e); 1.121 + } 1.122 + } 1.123 + 1.124 + /** Create a directory containing one or more files. */ 1.125 + File createDir(File dir, String... entries) throws Exception { 1.126 + if (!dir.mkdirs()) 1.127 + throw new Exception("cannot create directories " + dir); 1.128 + for (String e: entries) { 1.129 + writeFile(new File(dir, getPathForDirEntry(e)), getBodyForEntry(e)); 1.130 + } 1.131 + return dir; 1.132 + } 1.133 + 1.134 + /** Create a jar file containing one or more entries. */ 1.135 + File createJar(File jar, String... entries) throws IOException { 1.136 + OutputStream out = new FileOutputStream(jar); 1.137 + try { 1.138 + JarOutputStream jos = new JarOutputStream(out); 1.139 + for (String e: entries) { 1.140 + jos.putNextEntry(new JarEntry(getPathForZipEntry(e))); 1.141 + jos.write(getBodyForEntry(e).getBytes()); 1.142 + } 1.143 + jos.close(); 1.144 + } finally { 1.145 + out.close(); 1.146 + } 1.147 + return jar; 1.148 + } 1.149 + 1.150 + /** Return the path for an entry given to createDir */ 1.151 + String getPathForDirEntry(String e) { 1.152 + return e.replace(".", File.separator) + ".java"; 1.153 + } 1.154 + 1.155 + /** Return the path for an entry given to createJar. */ 1.156 + String getPathForZipEntry(String e) { 1.157 + return e.replace(".", "/") + ".java"; 1.158 + } 1.159 + 1.160 + /** Return the body text for an entry given to createDir or createJar. */ 1.161 + String getBodyForEntry(String e) { 1.162 + int sep = e.lastIndexOf("."); 1.163 + String pkgName = e.substring(0, sep); 1.164 + String className = e.substring(sep + 1); 1.165 + return "package " + pkgName + "; public class " + className + "{ class Inner { } }"; 1.166 + } 1.167 + 1.168 + /** Write a file containing the given string. Parent directories are 1.169 + * created as needed. */ 1.170 + File writeFile(File f, String s) throws IOException { 1.171 + if (f.getParentFile() != null) 1.172 + f.getParentFile().mkdirs(); 1.173 + FileWriter out = new FileWriter(f); 1.174 + try { 1.175 + out.write(s); 1.176 + } finally { 1.177 + out.close(); 1.178 + } 1.179 + return f; 1.180 + } 1.181 + 1.182 + /** Create a path value from a list of directories and jar files. */ 1.183 + String createPath(File... files) { 1.184 + StringBuilder sb = new StringBuilder(); 1.185 + for (File f: files) { 1.186 + if (sb.length() > 0) 1.187 + sb.append(File.pathSeparatorChar); 1.188 + sb.append(f.getPath()); 1.189 + } 1.190 + return sb.toString(); 1.191 + } 1.192 + 1.193 + /** Create a set of files from a base directory and a set of relative paths. */ 1.194 + Set<File> getFiles(File dir, String... paths) { 1.195 + Set<File> files = new LinkedHashSet<File>(); 1.196 + for (String p: paths) 1.197 + files.add(new File(dir, p)); 1.198 + return files; 1.199 + } 1.200 + 1.201 + /** Find all the files in a directory and its subdirectories. */ 1.202 + Set<File> findFiles(File dir) { 1.203 + Set<File> files = new LinkedHashSet<File>(); 1.204 + findFiles(dir, files); 1.205 + return files; 1.206 + } 1.207 + // where 1.208 + void findFiles(File dir, Set<File> files) { 1.209 + for (File f: dir.listFiles()) { 1.210 + if (f.isDirectory()) 1.211 + findFiles(f, files); 1.212 + else 1.213 + files.add(f); 1.214 + } 1.215 + } 1.216 + 1.217 + /** Return the difference of two sets, a - b. */ 1.218 + <T> Set<T> diff(Set<T> a, Set<T> b) { 1.219 + if (b.isEmpty()) 1.220 + return a; 1.221 + Set<T> result = new LinkedHashSet<T>(a); 1.222 + result.removeAll(b); 1.223 + return result; 1.224 + } 1.225 + 1.226 + /** Report an error. */ 1.227 + void error(String msg) { 1.228 + System.err.println(msg); 1.229 + errors++; 1.230 + } 1.231 + 1.232 + int errors; 1.233 +}