Fri, 29 Apr 2011 16:06:28 +0100
6550655: com.sun.tools.javac.code.Symbol$CompletionFailure
Summary: Accessing a non-existing enum constant from an annotation whose class is available results in an internal error
Reviewed-by: jjg
1 /*
2 * Copyright (c) 2009, 2011 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 */
24 /*
25 * @test
26 * @bug 6410367 6411310
27 * @summary FileObject should support user-friendly names via getName()
28 */
30 import java.io.*;
31 import java.util.*;
32 import java.util.jar.*;
33 import java.util.zip.*;
34 import javax.tools.*;
36 import com.sun.tools.javac.file.JavacFileManager;
37 import com.sun.tools.javac.util.Context;
38 import com.sun.tools.javac.util.Options;
40 // Test FileObject.getName returned from JavacFileManager and its support classes.
42 public class Test {
43 public static void main(String... args) throws Exception {
44 new Test().run();
45 }
47 Set<String> foundClasses = new TreeSet<String>();
48 Set<String> foundJars = new TreeSet<String>();
50 void run() throws Exception {
51 File rt_jar = findRtJar();
53 // names for entries to be created in directories and jar files
54 String[] entries = { "p/A.java", "p/A.class", "p/resources/A-1.html" };
56 // test various combinations of directories and jar files, intended to
57 // cover all sources of file objects within JavacFileManager's support classes
59 test(createFileManager(), createDir("dir", entries), "p", entries);
60 test(createFileManager(), createDir("a b/dir", entries), "p", entries);
62 for (boolean useOptimizedZip: new boolean[] { false, true }) {
63 test(createFileManager(useOptimizedZip), createJar("jar", entries), "p", entries);
64 test(createFileManager(useOptimizedZip), createJar("jar jar", entries), "p", entries);
66 for (boolean useSymbolFile: new boolean[] { false, true }) {
67 test(createFileManager(useOptimizedZip, useSymbolFile), rt_jar, "java.lang.ref", null);
68 }
69 }
71 if (errors > 0)
72 throw new Exception(errors + " errors found");
74 // Verify that we hit all the impl classes we intended
75 checkCoverage("classes", foundClasses,
76 "RegularFileObject", "SymbolFileObject", "ZipFileIndexFileObject", "ZipFileObject");
78 // Verify that we hit the jar files we intended, specifically ct.sym as well as rt.jar
79 checkCoverage("jar files", foundJars,
80 "ct.sym", "jar", "jar jar", "rt.jar");
81 }
83 // use a new file manager for each test
84 void test(StandardJavaFileManager fm, File f, String pkg, String[] entries) throws Exception {
85 System.err.println("Test " + f);
86 try {
87 if (f.isDirectory()) {
88 for (File dir: new File[] { f, f.getAbsoluteFile() }) {
89 for (String e: entries) {
90 JavaFileObject fo = fm.getJavaFileObjects(new File(dir, e)).iterator().next();
91 test(fo, dir, e);
92 }
93 }
94 }
96 fm.setLocation(StandardLocation.CLASS_PATH, Collections.singleton(f));
97 fm.setLocation(StandardLocation.SOURCE_PATH, Collections.singleton(f.getAbsoluteFile()));
98 for (StandardLocation l: EnumSet.of(StandardLocation.CLASS_PATH, StandardLocation.SOURCE_PATH)) {
99 for (JavaFileObject fo: fm.list(l, pkg, EnumSet.allOf(JavaFileObject.Kind.class), true)) {
100 // we could use fm.getLocation but the following guarantees we preserve the original filename
101 File dir = (l == StandardLocation.CLASS_PATH ? f : f.getAbsoluteFile());
102 char sep = (dir.isDirectory() ? File.separatorChar : '/');
103 String b = fm.inferBinaryName(l, fo);
104 String e = fo.getKind().extension;
105 test(fo, dir, b.replace('.', sep) + e);
106 }
107 }
108 } finally {
109 fm.close();
110 }
111 }
113 void test(JavaFileObject fo, File dir, String p) {
114 System.err.println("Test: " + fo);
115 String expect = dir.isDirectory() ? new File(dir, p).getPath() : (dir.getPath() + "(" + p + ")");
116 String found = fo.getName();
117 // if ct.sym is found, replace it with the equivalent rt.jar
118 String found2 = found.replaceAll("lib([\\\\/])ct.sym\\(META-INF/sym/rt.jar/", "jre$1lib$1rt.jar(");
119 if (!expect.equals(found2)) {
120 System.err.println("expected: " + expect);
121 System.err.println(" found: " + found);
122 if (!found.equals(found2))
123 System.err.println(" found2: " + found2);
124 error("Failed: " + fo);
125 }
127 // record the file object class name for coverage checks later
128 foundClasses.add(fo.getClass().getSimpleName());
130 if (found.contains("(")) {
131 // record access to the jar file for coverage checks later
132 foundJars.add(new File(found.substring(0, found.indexOf("("))).getName());
133 }
134 }
136 void checkCoverage(String label, Set<String> found, String... expect) throws Exception {
137 Set<String> e = new TreeSet<String>(Arrays.asList(expect));
138 if (!found.equals(e)) {
139 e.removeAll(found);
140 throw new Exception("expected " + label + " not used: " + e);
141 }
142 }
144 JavacFileManager createFileManager() {
145 return createFileManager(false, false);
146 }
148 JavacFileManager createFileManager(boolean useOptimizedZip) {
149 return createFileManager(useOptimizedZip, false);
150 }
152 JavacFileManager createFileManager(boolean useOptimizedZip, boolean useSymbolFile) {
153 Context c = new Context();
154 Options options = Options.instance(c);
156 options.put("useOptimizedZip", Boolean.toString(useOptimizedZip));
158 if (!useSymbolFile) {
159 options.put("ignore.symbol.file", "true");
160 }
161 return new JavacFileManager(c, false, null);
162 }
164 File createDir(String name, String... entries) throws Exception {
165 File dir = new File(name);
166 if (!dir.mkdirs())
167 throw new Exception("cannot create directories " + dir);
168 for (String e: entries) {
169 writeFile(new File(dir, e), e);
170 }
171 return dir;
172 }
174 File createJar(String name, String... entries) throws IOException {
175 File jar = new File(name);
176 OutputStream out = new FileOutputStream(jar);
177 try {
178 JarOutputStream jos = new JarOutputStream(out);
179 for (String e: entries) {
180 jos.putNextEntry(new ZipEntry(e));
181 jos.write(e.getBytes());
182 }
183 jos.close();
184 } finally {
185 out.close();
186 }
187 return jar;
188 }
190 File findRtJar() throws Exception {
191 File java_home = new File(System.getProperty("java.home"));
192 if (java_home.getName().equals("jre"))
193 java_home = java_home.getParentFile();
194 File rt_jar = new File(new File(new File(java_home, "jre"), "lib"), "rt.jar");
195 if (!rt_jar.exists())
196 throw new Exception("can't find rt.jar");
197 return rt_jar;
198 }
200 byte[] read(InputStream in) throws IOException {
201 byte[] data = new byte[1024];
202 int offset = 0;
203 try {
204 int n;
205 while ((n = in.read(data, offset, data.length - offset)) != -1) {
206 offset += n;
207 if (offset == data.length)
208 data = Arrays.copyOf(data, 2 * data.length);
209 }
210 } finally {
211 in.close();
212 }
213 return Arrays.copyOf(data, offset);
214 }
216 void writeFile(File f, String s) throws IOException {
217 f.getParentFile().mkdirs();
218 FileWriter out = new FileWriter(f);
219 try {
220 out.write(s);
221 } finally {
222 out.close();
223 }
224 }
226 void error(String msg) {
227 System.err.println(msg);
228 errors++;
229 }
231 int errors;
232 }