jjg@415: /* ksrini@882: * Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. jjg@415: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. jjg@415: * jjg@415: * This code is free software; you can redistribute it and/or modify it jjg@415: * under the terms of the GNU General Public License version 2 only, as jjg@415: * published by the Free Software Foundation. jjg@415: * jjg@415: * This code is distributed in the hope that it will be useful, but WITHOUT jjg@415: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or jjg@415: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License jjg@415: * version 2 for more details (a copy is included in the LICENSE file that jjg@415: * accompanied this code). jjg@415: * jjg@415: * You should have received a copy of the GNU General Public License version jjg@415: * 2 along with this work; if not, write to the Free Software Foundation, jjg@415: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. jjg@415: * ohair@554: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ohair@554: * or visit www.oracle.com if you need additional information or have any ohair@554: * questions. jjg@415: */ jjg@415: jjg@415: /* jjg@415: * @test jjg@415: * @bug 4241573 jjg@415: * @summary SourceFile attribute includes full path jjg@415: */ jjg@415: jjg@415: import com.sun.tools.classfile.Attribute; jjg@415: import com.sun.tools.classfile.ClassFile; jjg@415: import com.sun.tools.classfile.SourceFile_attribute; jjg@415: import java.io.*; jjg@415: import java.util.*; jjg@415: import java.util.jar.*; jjg@415: jjg@415: public class T4241573 { jjg@415: public static void main(String... args) throws Exception { jjg@415: new T4241573().run(); jjg@415: } jjg@415: jjg@415: public void run() throws Exception { jjg@415: // Selection of files to be compiled jjg@415: File absJar = createJar(new File("abs.jar").getAbsoluteFile(), "j.A"); jjg@415: File relJar = createJar(new File("rel.jar"), "j.R"); jjg@415: File absDir = createDir(new File("abs.dir").getAbsoluteFile(), "d.A"); jjg@415: File relDir = createDir(new File("rel.dir"), "d.R"); jjg@415: File absTestFile = writeFile(new File("AbsTest.java").getAbsoluteFile(), "class AbsTest { class Inner { } }"); jjg@415: File relTestFile = writeFile(new File("RelTest.java"), "class RelTest { class Inner { } }"); jjg@415: File relTest2File = writeFile(new File("p/RelTest2.java"), "package p; class RelTest2 { class Inner { } }"); jjg@415: // This next class references other classes that will be found on the source path jjg@415: // and which will therefore need to be compiled as well. jjg@415: File mainFile = writeFile(new File("Main.java"), jjg@415: "class Main { j.A ja; j.R jr; d.A da; d.R dr; }" + jjg@415: ""); jjg@415: jjg@415: String sourcePath = createPath(absJar, relJar, absDir, relDir); jjg@415: File outDir = new File("classes"); jjg@415: outDir.mkdirs(); jjg@415: jjg@415: String[] args = { jjg@415: "-sourcepath", sourcePath, jjg@415: "-d", outDir.getPath(), jjg@415: absTestFile.getPath(), jjg@415: relTestFile.getPath(), jjg@415: relTest2File.getPath(), jjg@415: mainFile.getPath(), jjg@415: }; jjg@415: System.err.println("compile: " + Arrays.asList(args)); jjg@415: StringWriter sw = new StringWriter(); jjg@415: PrintWriter pw = new PrintWriter(sw); jjg@415: int rc = com.sun.tools.javac.Main.compile(args, pw); jjg@415: pw.close(); jjg@415: if (rc != 0) { jjg@415: System.err.println(sw.toString()); jjg@415: throw new Exception("unexpected exit from javac: " + rc); jjg@415: } jjg@415: jjg@415: Set expect = getFiles(outDir, jjg@415: "d/A.class", "d/A$Inner.class", jjg@415: "d/R.class", "d/R$Inner.class", jjg@415: "j/A.class", "j/A$Inner.class", jjg@415: "j/R.class", "j/R$Inner.class", jjg@415: "AbsTest.class", "AbsTest$Inner.class", jjg@415: "RelTest.class", "RelTest$Inner.class", jjg@415: "p/RelTest2.class", "p/RelTest2$Inner.class", jjg@415: "Main.class" ); jjg@415: jjg@415: Set found = findFiles(outDir); jjg@415: jjg@415: if (!found.equals(expect)) { jjg@415: if (found.containsAll(expect)) jjg@415: throw new Exception("unexpected files found: " + diff(found, expect)); jjg@415: else if (expect.containsAll(found)) jjg@415: throw new Exception("expected files not found: " + diff(expect, found)); jjg@415: } jjg@415: jjg@415: for (File f: found) jjg@415: verifySourceFileAttribute(f); jjg@415: jjg@415: if (errors > 0) jjg@415: throw new Exception(errors + " errors occurred"); jjg@415: } jjg@415: jjg@415: /** Check the SourceFileAttribute is the simple name of the original source file. */ jjg@415: void verifySourceFileAttribute(File f) { jjg@415: System.err.println("verify: " + f); jjg@415: try { jjg@415: ClassFile cf = ClassFile.read(f); jjg@415: SourceFile_attribute sfa = (SourceFile_attribute) cf.getAttribute(Attribute.SourceFile); jjg@415: String found = sfa.getSourceFile(cf.constant_pool); jjg@415: String expect = f.getName().replaceAll("([$.].*)?\\.class", ".java"); jjg@415: if (!expect.equals(found)) { jjg@415: error("bad value found: " + found + ", expected: " + expect); jjg@415: } jjg@415: } catch (Exception e) { jjg@415: error("error reading " + f +": " + e); jjg@415: } jjg@415: } jjg@415: jjg@415: /** Create a directory containing one or more files. */ jjg@415: File createDir(File dir, String... entries) throws Exception { jjg@415: if (!dir.mkdirs()) jjg@415: throw new Exception("cannot create directories " + dir); jjg@415: for (String e: entries) { ksrini@882: writeFile(new File(dir, getPathForDirEntry(e)), getBodyForEntry(e)); jjg@415: } jjg@415: return dir; jjg@415: } jjg@415: jjg@415: /** Create a jar file containing one or more entries. */ jjg@415: File createJar(File jar, String... entries) throws IOException { jjg@415: OutputStream out = new FileOutputStream(jar); jjg@415: try { jjg@415: JarOutputStream jos = new JarOutputStream(out); jjg@415: for (String e: entries) { ksrini@882: jos.putNextEntry(new JarEntry(getPathForZipEntry(e))); jjg@415: jos.write(getBodyForEntry(e).getBytes()); jjg@415: } jjg@415: jos.close(); jjg@415: } finally { jjg@415: out.close(); jjg@415: } jjg@415: return jar; jjg@415: } jjg@415: ksrini@882: /** Return the path for an entry given to createDir */ ksrini@882: String getPathForDirEntry(String e) { jjg@415: return e.replace(".", File.separator) + ".java"; jjg@415: } jjg@415: ksrini@882: /** Return the path for an entry given to createJar. */ ksrini@882: String getPathForZipEntry(String e) { ksrini@882: return e.replace(".", "/") + ".java"; ksrini@882: } ksrini@882: jjg@415: /** Return the body text for an entry given to createDir or createJar. */ jjg@415: String getBodyForEntry(String e) { jjg@415: int sep = e.lastIndexOf("."); jjg@415: String pkgName = e.substring(0, sep); jjg@415: String className = e.substring(sep + 1); jjg@415: return "package " + pkgName + "; public class " + className + "{ class Inner { } }"; jjg@415: } jjg@415: jjg@415: /** Write a file containing the given string. Parent directories are jjg@415: * created as needed. */ jjg@415: File writeFile(File f, String s) throws IOException { jjg@415: if (f.getParentFile() != null) jjg@415: f.getParentFile().mkdirs(); jjg@415: FileWriter out = new FileWriter(f); jjg@415: try { jjg@415: out.write(s); jjg@415: } finally { jjg@415: out.close(); jjg@415: } jjg@415: return f; jjg@415: } jjg@415: jjg@415: /** Create a path value from a list of directories and jar files. */ jjg@415: String createPath(File... files) { jjg@415: StringBuilder sb = new StringBuilder(); jjg@415: for (File f: files) { jjg@415: if (sb.length() > 0) jjg@415: sb.append(File.pathSeparatorChar); jjg@415: sb.append(f.getPath()); jjg@415: } jjg@415: return sb.toString(); jjg@415: } jjg@415: jjg@415: /** Create a set of files from a base directory and a set of relative paths. */ jjg@415: Set getFiles(File dir, String... paths) { jjg@415: Set files = new LinkedHashSet(); jjg@415: for (String p: paths) jjg@415: files.add(new File(dir, p)); jjg@415: return files; jjg@415: } jjg@415: jjg@415: /** Find all the files in a directory and its subdirectories. */ jjg@415: Set findFiles(File dir) { jjg@415: Set files = new LinkedHashSet(); jjg@415: findFiles(dir, files); jjg@415: return files; jjg@415: } jjg@415: // where jjg@415: void findFiles(File dir, Set files) { jjg@415: for (File f: dir.listFiles()) { jjg@415: if (f.isDirectory()) jjg@415: findFiles(f, files); jjg@415: else jjg@415: files.add(f); jjg@415: } jjg@415: } jjg@415: jjg@415: /** Return the difference of two sets, a - b. */ jjg@415: Set diff(Set a, Set b) { jjg@415: if (b.isEmpty()) jjg@415: return a; jjg@415: Set result = new LinkedHashSet(a); jjg@415: result.removeAll(b); jjg@415: return result; jjg@415: } jjg@415: jjg@415: /** Report an error. */ jjg@415: void error(String msg) { jjg@415: System.err.println(msg); jjg@415: errors++; jjg@415: } jjg@415: jjg@415: int errors; jjg@415: }