Wed, 21 Sep 2011 21:56:53 -0700
7092965: javac should not close processorClassLoader before end of compilation
Reviewed-by: darcy
1 /*
2 * Copyright (c) 2006, 2008, 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.tools.javac.sym;
28 import com.sun.tools.javac.api.JavacTaskImpl;
29 import com.sun.tools.javac.code.Kinds;
30 import com.sun.tools.javac.code.Scope;
31 import com.sun.tools.javac.code.Symbol.*;
32 import com.sun.tools.javac.code.Symbol;
33 import com.sun.tools.javac.code.Attribute;
34 import com.sun.tools.javac.code.Symtab;
35 import com.sun.tools.javac.code.Type;
36 import com.sun.tools.javac.jvm.ClassReader;
37 import com.sun.tools.javac.jvm.ClassWriter;
38 import com.sun.tools.javac.jvm.Pool;
39 import com.sun.tools.javac.processing.JavacProcessingEnvironment;
40 import com.sun.tools.javac.util.List;
41 import com.sun.tools.javac.util.Pair;
43 import java.io.File;
44 import java.io.IOException;
45 import java.util.ArrayList;
46 import java.util.EnumSet;
47 import java.util.Enumeration;
48 import java.util.HashSet;
49 import java.util.ResourceBundle;
50 import java.util.Set;
52 import javax.annotation.processing.AbstractProcessor;
53 import javax.annotation.processing.RoundEnvironment;
54 import javax.annotation.processing.SupportedAnnotationTypes;
55 import javax.annotation.processing.SupportedOptions;
56 import javax.lang.model.SourceVersion;
57 import javax.lang.model.element.ElementKind;
58 import javax.lang.model.element.TypeElement;
59 import javax.tools.Diagnostic;
60 import javax.tools.JavaCompiler;
61 import javax.tools.JavaFileManager.Location;
62 import javax.tools.JavaFileObject;
63 import static javax.tools.JavaFileObject.Kind.CLASS;
64 import javax.tools.StandardJavaFileManager;
65 import javax.tools.StandardLocation;
66 import javax.tools.ToolProvider;
68 /**
69 * Used to generate a "symbol file" representing rt.jar that only
70 * includes supported or legacy proprietary API. Valid annotation
71 * processor options:
72 *
73 * <dl>
74 * <dt>com.sun.tools.javac.sym.Jar</dt>
75 * <dd>Specifies the location of rt.jar.</dd>
76 * <dt>com.sun.tools.javac.sym.Dest</dt>
77 * <dd>Specifies the destination directory.</dd>
78 * </dl>
79 *
80 * <p><b>This is NOT part of any supported API.
81 * If you write code that depends on this, you do so at your own
82 * risk. This code and its internal interfaces are subject to change
83 * or deletion without notice.</b></p>
84 *
85 * @author Peter von der Ah\u00e9
86 */
87 @SupportedOptions({"com.sun.tools.javac.sym.Jar","com.sun.tools.javac.sym.Dest"})
88 @SupportedAnnotationTypes("*")
89 public class CreateSymbols extends AbstractProcessor {
91 static Set<String> getLegacyPackages() {
92 ResourceBundle legacyBundle
93 = ResourceBundle.getBundle("com.sun.tools.javac.resources.legacy");
94 Set<String> keys = new HashSet<String>();
95 for (Enumeration<String> e = legacyBundle.getKeys(); e.hasMoreElements(); )
96 keys.add(e.nextElement());
97 return keys;
98 }
100 public boolean process(Set<? extends TypeElement> tes, RoundEnvironment renv) {
101 try {
102 if (renv.processingOver())
103 createSymbols();
104 } catch (IOException e) {
105 processingEnv.getMessager()
106 .printMessage(Diagnostic.Kind.ERROR, e.getLocalizedMessage());
107 } catch (Throwable t) {
108 Throwable cause = t.getCause();
109 if (cause == null)
110 cause = t;
111 processingEnv.getMessager()
112 .printMessage(Diagnostic.Kind.ERROR, cause.getLocalizedMessage());
113 }
114 return true;
115 }
117 void createSymbols() throws IOException {
118 Set<String> legacy = getLegacyPackages();
119 Set<String> legacyProprietary = getLegacyPackages();
120 Set<String> documented = new HashSet<String>();
121 Set<PackageSymbol> packages =
122 ((JavacProcessingEnvironment)processingEnv).getSpecifiedPackages();
123 String jarName = processingEnv.getOptions().get("com.sun.tools.javac.sym.Jar");
124 if (jarName == null)
125 throw new RuntimeException("Must use -Acom.sun.tools.javac.sym.Jar=LOCATION_OF_JAR");
126 String destName = processingEnv.getOptions().get("com.sun.tools.javac.sym.Dest");
127 if (destName == null)
128 throw new RuntimeException("Must use -Acom.sun.tools.javac.sym.Dest=LOCATION_OF_JAR");
130 for (PackageSymbol psym : packages) {
131 String name = psym.getQualifiedName().toString();
132 legacyProprietary.remove(name);
133 documented.add(name);
134 }
136 JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
137 StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
138 Location jarLocation = StandardLocation.locationFor(jarName);
139 File jarFile = new File(jarName);
140 fm.setLocation(jarLocation, List.of(jarFile));
141 fm.setLocation(StandardLocation.CLASS_PATH, List.<File>nil());
142 fm.setLocation(StandardLocation.SOURCE_PATH, List.<File>nil());
143 {
144 ArrayList<File> bootClassPath = new ArrayList<File>();
145 bootClassPath.add(jarFile);
146 for (File path : fm.getLocation(StandardLocation.PLATFORM_CLASS_PATH)) {
147 if (!new File(path.getName()).equals(new File("rt.jar")))
148 bootClassPath.add(path);
149 }
150 System.err.println("Using boot class path = " + bootClassPath);
151 fm.setLocation(StandardLocation.PLATFORM_CLASS_PATH, bootClassPath);
152 }
153 // System.out.println(fm.getLocation(StandardLocation.PLATFORM_CLASS_PATH));
154 File destDir = new File(destName);
155 if (!destDir.exists())
156 if (!destDir.mkdirs())
157 throw new RuntimeException("Could not create " + destDir);
158 fm.setLocation(StandardLocation.CLASS_OUTPUT, List.of(destDir));
159 Set<String> hiddenPackages = new HashSet<String>();
160 Set<String> crisp = new HashSet<String>();
161 List<String> options = List.of("-XDdev");
162 // options = options.prepend("-doe");
163 // options = options.prepend("-verbose");
164 JavacTaskImpl task = (JavacTaskImpl)
165 tool.getTask(null, fm, null, options, null, null);
166 com.sun.tools.javac.main.JavaCompiler compiler =
167 com.sun.tools.javac.main.JavaCompiler.instance(task.getContext());
168 ClassReader reader = ClassReader.instance(task.getContext());
169 ClassWriter writer = ClassWriter.instance(task.getContext());
170 Symtab syms = Symtab.instance(task.getContext());
171 Attribute.Compound proprietary =
172 new Attribute.Compound(syms.proprietaryType,
173 List.<Pair<Symbol.MethodSymbol,Attribute>>nil());
175 Type.moreInfo = true;
176 Pool pool = new Pool();
177 for (JavaFileObject file : fm.list(jarLocation, "", EnumSet.of(CLASS), true)) {
178 String className = fm.inferBinaryName(jarLocation, file);
179 int index = className.lastIndexOf('.');
180 String pckName = index == -1 ? "" : className.substring(0, index);
181 boolean addLegacyAnnotation = false;
182 if (documented.contains(pckName)) {
183 if (!legacy.contains(pckName))
184 crisp.add(pckName);
185 // System.out.println("Documented: " + className);
186 } else if (legacyProprietary.contains(pckName)) {
187 addLegacyAnnotation = true;
188 // System.out.println("Legacy proprietary: " + className);
189 } else {
190 // System.out.println("Hidden " + className);
191 hiddenPackages.add(pckName);
192 continue;
193 }
194 TypeSymbol sym = (TypeSymbol)compiler.resolveIdent(className);
195 if (sym.kind != Kinds.TYP) {
196 if (className.indexOf('$') < 0) {
197 System.err.println("Ignoring (other) " + className + " : " + sym);
198 System.err.println(" " + sym.getClass().getSimpleName() + " " + sym.type);
199 }
200 continue;
201 }
202 sym.complete();
203 if (sym.getEnclosingElement().getKind() != ElementKind.PACKAGE) {
204 System.err.println("Ignoring (bad) " + sym.getQualifiedName());
205 continue;
206 }
207 ClassSymbol cs = (ClassSymbol) sym;
208 if (addLegacyAnnotation) {
209 cs.attributes_field = (cs.attributes_field == null)
210 ? List.of(proprietary)
211 : cs.attributes_field.prepend(proprietary);
212 }
213 writeClass(pool, cs, writer);
214 }
216 if (false) {
217 for (String pckName : crisp)
218 System.out.println("Crisp: " + pckName);
219 for (String pckName : hiddenPackages)
220 System.out.println("Hidden: " + pckName);
221 for (String pckName : legacyProprietary)
222 System.out.println("Legacy proprietary: " + pckName);
223 for (String pckName : documented)
224 System.out.println("Documented: " + pckName);
225 }
226 }
228 void writeClass(final Pool pool, final ClassSymbol cs, final ClassWriter writer)
229 throws IOException
230 {
231 try {
232 pool.reset();
233 cs.pool = pool;
234 writer.writeClass(cs);
235 for (Scope.Entry e = cs.members().elems; e != null; e = e.sibling) {
236 if (e.sym.kind == Kinds.TYP) {
237 ClassSymbol nestedClass = (ClassSymbol)e.sym;
238 nestedClass.complete();
239 writeClass(pool, nestedClass, writer);
240 }
241 }
242 } catch (ClassWriter.StringOverflow ex) {
243 throw new RuntimeException(ex);
244 } catch (ClassWriter.PoolOverflow ex) {
245 throw new RuntimeException(ex);
246 }
247 }
249 public SourceVersion getSupportedSourceVersion() {
250 return SourceVersion.latest();
251 }
253 // used for debugging
254 public static void main(String... args) {
255 String rt_jar = args[0];
256 String dest = args[1];
257 args = new String[] {
258 "-Xbootclasspath:" + rt_jar,
259 "-XDprocess.packages",
260 "-proc:only",
261 "-processor",
262 "com.sun.tools.javac.sym.CreateSymbols",
263 "-Acom.sun.tools.javac.sym.Jar=" + rt_jar,
264 "-Acom.sun.tools.javac.sym.Dest=" + dest,
265 // <editor-fold defaultstate="collapsed">
266 "java.applet",
267 "java.awt",
268 "java.awt.color",
269 "java.awt.datatransfer",
270 "java.awt.dnd",
271 "java.awt.event",
272 "java.awt.font",
273 "java.awt.geom",
274 "java.awt.im",
275 "java.awt.im.spi",
276 "java.awt.image",
277 "java.awt.image.renderable",
278 "java.awt.print",
279 "java.beans",
280 "java.beans.beancontext",
281 "java.io",
282 "java.lang",
283 "java.lang.annotation",
284 "java.lang.instrument",
285 "java.lang.management",
286 "java.lang.ref",
287 "java.lang.reflect",
288 "java.math",
289 "java.net",
290 "java.nio",
291 "java.nio.channels",
292 "java.nio.channels.spi",
293 "java.nio.charset",
294 "java.nio.charset.spi",
295 "java.rmi",
296 "java.rmi.activation",
297 "java.rmi.dgc",
298 "java.rmi.registry",
299 "java.rmi.server",
300 "java.security",
301 "java.security.acl",
302 "java.security.cert",
303 "java.security.interfaces",
304 "java.security.spec",
305 "java.sql",
306 "java.text",
307 "java.text.spi",
308 "java.util",
309 "java.util.concurrent",
310 "java.util.concurrent.atomic",
311 "java.util.concurrent.locks",
312 "java.util.jar",
313 "java.util.logging",
314 "java.util.prefs",
315 "java.util.regex",
316 "java.util.spi",
317 "java.util.zip",
318 "javax.accessibility",
319 "javax.activation",
320 "javax.activity",
321 "javax.annotation",
322 "javax.annotation.processing",
323 "javax.crypto",
324 "javax.crypto.interfaces",
325 "javax.crypto.spec",
326 "javax.imageio",
327 "javax.imageio.event",
328 "javax.imageio.metadata",
329 "javax.imageio.plugins.jpeg",
330 "javax.imageio.plugins.bmp",
331 "javax.imageio.spi",
332 "javax.imageio.stream",
333 "javax.jws",
334 "javax.jws.soap",
335 "javax.lang.model",
336 "javax.lang.model.element",
337 "javax.lang.model.type",
338 "javax.lang.model.util",
339 "javax.management",
340 "javax.management.loading",
341 "javax.management.monitor",
342 "javax.management.relation",
343 "javax.management.openmbean",
344 "javax.management.timer",
345 "javax.management.modelmbean",
346 "javax.management.remote",
347 "javax.management.remote.rmi",
348 "javax.naming",
349 "javax.naming.directory",
350 "javax.naming.event",
351 "javax.naming.ldap",
352 "javax.naming.spi",
353 "javax.net",
354 "javax.net.ssl",
355 "javax.print",
356 "javax.print.attribute",
357 "javax.print.attribute.standard",
358 "javax.print.event",
359 "javax.rmi",
360 "javax.rmi.CORBA",
361 "javax.rmi.ssl",
362 "javax.script",
363 "javax.security.auth",
364 "javax.security.auth.callback",
365 "javax.security.auth.kerberos",
366 "javax.security.auth.login",
367 "javax.security.auth.spi",
368 "javax.security.auth.x500",
369 "javax.security.cert",
370 "javax.security.sasl",
371 "javax.sound.sampled",
372 "javax.sound.sampled.spi",
373 "javax.sound.midi",
374 "javax.sound.midi.spi",
375 "javax.sql",
376 "javax.sql.rowset",
377 "javax.sql.rowset.serial",
378 "javax.sql.rowset.spi",
379 "javax.swing",
380 "javax.swing.border",
381 "javax.swing.colorchooser",
382 "javax.swing.filechooser",
383 "javax.swing.event",
384 "javax.swing.table",
385 "javax.swing.text",
386 "javax.swing.text.html",
387 "javax.swing.text.html.parser",
388 "javax.swing.text.rtf",
389 "javax.swing.tree",
390 "javax.swing.undo",
391 "javax.swing.plaf",
392 "javax.swing.plaf.basic",
393 "javax.swing.plaf.metal",
394 "javax.swing.plaf.multi",
395 "javax.swing.plaf.synth",
396 "javax.tools",
397 "javax.transaction",
398 "javax.transaction.xa",
399 "javax.xml.parsers",
400 "javax.xml.bind",
401 "javax.xml.bind.annotation",
402 "javax.xml.bind.annotation.adapters",
403 "javax.xml.bind.attachment",
404 "javax.xml.bind.helpers",
405 "javax.xml.bind.util",
406 "javax.xml.soap",
407 "javax.xml.ws",
408 "javax.xml.ws.handler",
409 "javax.xml.ws.handler.soap",
410 "javax.xml.ws.http",
411 "javax.xml.ws.soap",
412 "javax.xml.ws.spi",
413 "javax.xml.transform",
414 "javax.xml.transform.sax",
415 "javax.xml.transform.dom",
416 "javax.xml.transform.stax",
417 "javax.xml.transform.stream",
418 "javax.xml",
419 "javax.xml.crypto",
420 "javax.xml.crypto.dom",
421 "javax.xml.crypto.dsig",
422 "javax.xml.crypto.dsig.dom",
423 "javax.xml.crypto.dsig.keyinfo",
424 "javax.xml.crypto.dsig.spec",
425 "javax.xml.datatype",
426 "javax.xml.validation",
427 "javax.xml.namespace",
428 "javax.xml.xpath",
429 "javax.xml.stream",
430 "javax.xml.stream.events",
431 "javax.xml.stream.util",
432 "org.ietf.jgss",
433 "org.omg.CORBA",
434 "org.omg.CORBA.DynAnyPackage",
435 "org.omg.CORBA.ORBPackage",
436 "org.omg.CORBA.TypeCodePackage",
437 "org.omg.stub.java.rmi",
438 "org.omg.CORBA.portable",
439 "org.omg.CORBA_2_3",
440 "org.omg.CORBA_2_3.portable",
441 "org.omg.CosNaming",
442 "org.omg.CosNaming.NamingContextExtPackage",
443 "org.omg.CosNaming.NamingContextPackage",
444 "org.omg.SendingContext",
445 "org.omg.PortableServer",
446 "org.omg.PortableServer.CurrentPackage",
447 "org.omg.PortableServer.POAPackage",
448 "org.omg.PortableServer.POAManagerPackage",
449 "org.omg.PortableServer.ServantLocatorPackage",
450 "org.omg.PortableServer.portable",
451 "org.omg.PortableInterceptor",
452 "org.omg.PortableInterceptor.ORBInitInfoPackage",
453 "org.omg.Messaging",
454 "org.omg.IOP",
455 "org.omg.IOP.CodecFactoryPackage",
456 "org.omg.IOP.CodecPackage",
457 "org.omg.Dynamic",
458 "org.omg.DynamicAny",
459 "org.omg.DynamicAny.DynAnyPackage",
460 "org.omg.DynamicAny.DynAnyFactoryPackage",
461 "org.w3c.dom",
462 "org.w3c.dom.events",
463 "org.w3c.dom.bootstrap",
464 "org.w3c.dom.ls",
465 "org.xml.sax",
466 "org.xml.sax.ext",
467 "org.xml.sax.helpers",
468 "com.sun.java.browser.dom",
469 "org.w3c.dom",
470 "org.w3c.dom.bootstrap",
471 "org.w3c.dom.ls",
472 "org.w3c.dom.ranges",
473 "org.w3c.dom.traversal",
474 "org.w3c.dom.html",
475 "org.w3c.dom.stylesheets",
476 "org.w3c.dom.css",
477 "org.w3c.dom.events",
478 "org.w3c.dom.views",
479 "com.sun.management",
480 "com.sun.security.auth",
481 "com.sun.security.auth.callback",
482 "com.sun.security.auth.login",
483 "com.sun.security.auth.module",
484 "com.sun.security.jgss",
485 "com.sun.net.httpserver",
486 "com.sun.net.httpserver.spi",
487 "javax.smartcardio"
488 // </editor-fold>
489 };
490 com.sun.tools.javac.Main.compile(args);
491 }
493 }