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