Fri, 24 Apr 2020 03:58:51 +0100
Merge
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 6877206
27 * @summary JavaFileObject.toUri returns bogus URI (win)
28 */
30 import java.io.*;
31 import java.net.*;
32 import java.util.*;
33 import java.util.jar.*;
34 import java.util.zip.*;
35 import javax.tools.*;
37 import com.sun.tools.javac.file.JavacFileManager;
38 import com.sun.tools.javac.util.Context;
39 import com.sun.tools.javac.util.Options;
41 // Test URIs returned from JavacFileManager and its support classes.
42 // For a variety of file objects, verify the validity of FileObject.toUri()
43 // by verifying the URI exists and points to the same contents as the file
44 // object itself
46 public class T6877206 {
47 public static void main(String... args) throws Exception {
48 new T6877206().run();
49 }
51 Set<String> foundClasses = new TreeSet<String>();
52 Set<String> foundJars = new TreeSet<String>();
54 void run() throws Exception {
55 File rt_jar = findRtJar();
57 // names for entries to be created in directories and jar files
58 String[] entries = { "p/A.class", "p/resources/A-1.jpg" };
60 // test various combinations of directories and jar files, intended to
61 // cover all sources of URIs within JavacFileManager's support classes
63 test(createFileManager(), createDir("dir", entries), "p", entries.length);
64 test(createFileManager(), createDir("a b/dir", entries), "p", entries.length);
66 for (boolean useOptimizedZip: new boolean[] { false, true }) {
67 test(createFileManager(useOptimizedZip), createJar("jar", entries), "p", entries.length);
68 test(createFileManager(useOptimizedZip), createJar("jar jar", entries), "p", entries.length);
70 for (boolean useSymbolFile: new boolean[] { false, true }) {
71 test(createFileManager(useOptimizedZip, useSymbolFile), rt_jar, "java.lang.ref", -1);
72 }
73 }
75 // Verify that we hit all the impl classes we intended
76 checkCoverage("classes", foundClasses,
77 "RegularFileObject", "SymbolFileObject", "ZipFileIndexFileObject", "ZipFileObject");
79 // Verify that we hit the jar files we intended, specifically ct.sym as well as rt.jar
80 checkCoverage("jar files", foundJars,
81 "ct.sym", "jar", "jar jar", "rt.jar");
82 }
84 // use a new file manager for each test
85 void test(StandardJavaFileManager fm, File f, String pkg, int expect) throws Exception {
86 JarURLConnection c;
87 System.err.println("Test " + f);
88 try {
89 fm.setLocation(StandardLocation.CLASS_PATH, Collections.singleton(f));
91 int count = 0;
92 for (JavaFileObject fo: fm.list(StandardLocation.CLASS_PATH,
93 pkg, EnumSet.allOf(JavaFileObject.Kind.class), true)) {
94 System.err.println("checking " + fo);
95 // record the file object class name for coverage checks later
96 foundClasses.add(fo.getClass().getSimpleName());
97 testFileObject(fo);
98 count++;
99 }
101 if (expect > 0 && count != expect)
102 throw new Exception("wrong number of entries found: "
103 + count + ", expected " + expect);
104 } finally {
105 fm.close();
106 }
107 }
109 void testFileObject(JavaFileObject fo) throws Exception {
110 // test the validity of the result of toUri() by using URLConnection
111 // and comparing the results of reading from the connection with the
112 // result of reading from the file object directly.
113 URI uri = fo.toUri();
114 System.err.println("uri: " + uri);
116 URLConnection urlconn = uri.toURL().openConnection();
117 if (urlconn instanceof JarURLConnection) {
118 JarURLConnection jarconn = (JarURLConnection) urlconn;
119 File f = new File(jarconn.getJarFile().getName());
120 // record access to the jar file for coverage checks later
121 foundJars.add(f.getName());
122 }
124 try {
125 byte[] uriData = read(urlconn.getInputStream());
126 byte[] foData = read(fo.openInputStream());
127 if (!Arrays.equals(uriData, foData)) {
128 if (uriData.length != foData.length)
129 throw new Exception("data size differs: uri data "
130 + uriData.length + " bytes, fo data " + foData.length+ " bytes");
131 for (int i = 0; i < uriData.length; i++) {
132 if (uriData[i] != foData[i])
133 throw new Exception("unexpected data returned at offset " + i
134 + ", uri data " + uriData[i] + ", fo data " + foData[i]);
135 }
136 throw new AssertionError("cannot find difference");
137 }
138 } finally {
139 // In principle, simply closing the result of urlconn.getInputStream()
140 // should have been sufficient. But the internal JarURLConnection
141 // does not close the JarFile in an expeditious manner, thus preventing
142 // jtreg from deleting the jar file before starting the next test.
143 // Therefore we force access to the JarURLConnection to close the
144 // JarFile when necessary.
145 if (urlconn instanceof JarURLConnection) {
146 JarURLConnection jarconn = (JarURLConnection) urlconn;
147 jarconn.getJarFile().close();
148 }
149 }
150 }
152 void checkCoverage(String label, Set<String> found, String... expect) throws Exception {
153 Set<String> e = new TreeSet<String>(Arrays.asList(expect));
154 if (!found.equals(e)) {
155 e.removeAll(found);
156 throw new Exception("expected " + label + " not used: " + e);
157 }
158 }
160 JavacFileManager createFileManager() {
161 return createFileManager(false, false);
162 }
164 JavacFileManager createFileManager(boolean useOptimizedZip) {
165 return createFileManager(useOptimizedZip, false);
166 }
168 JavacFileManager createFileManager(boolean useOptimizedZip, boolean useSymbolFile) {
169 Context ctx = new Context();
170 Options options = Options.instance(ctx);
171 options.put("useOptimizedZip", Boolean.toString(useOptimizedZip));
172 if (!useSymbolFile) {
173 options.put("ignore.symbol.file", "true");
174 }
175 return new JavacFileManager(ctx, false, null);
176 }
178 File createDir(String name, String... entries) throws Exception {
179 File dir = new File(name);
180 if (!dir.mkdirs())
181 throw new Exception("cannot create directories " + dir);
182 for (String e: entries) {
183 writeFile(new File(dir, e), e);
184 }
185 return dir;
186 }
188 File createJar(String name, String... entries) throws IOException {
189 File jar = new File(name);
190 OutputStream out = new FileOutputStream(jar);
191 try {
192 JarOutputStream jos = new JarOutputStream(out);
193 for (String e: entries) {
194 jos.putNextEntry(new ZipEntry(e));
195 jos.write(e.getBytes());
196 }
197 jos.close();
198 } finally {
199 out.close();
200 }
201 return jar;
202 }
204 File findRtJar() throws Exception {
205 File java_home = new File(System.getProperty("java.home"));
206 if (java_home.getName().equals("jre"))
207 java_home = java_home.getParentFile();
208 File rt_jar = new File(new File(new File(java_home, "jre"), "lib"), "rt.jar");
209 if (!rt_jar.exists())
210 throw new Exception("can't find rt.jar");
211 return rt_jar;
212 }
214 byte[] read(InputStream in) throws IOException {
215 byte[] data = new byte[1024];
216 int offset = 0;
217 try {
218 int n;
219 while ((n = in.read(data, offset, data.length - offset)) != -1) {
220 offset += n;
221 if (offset == data.length)
222 data = Arrays.copyOf(data, 2 * data.length);
223 }
224 } finally {
225 in.close();
226 }
227 return Arrays.copyOf(data, offset);
228 }
230 void writeFile(File f, String s) throws IOException {
231 f.getParentFile().mkdirs();
232 FileWriter out = new FileWriter(f);
233 try {
234 out.write(s);
235 } finally {
236 out.close();
237 }
238 }
239 }