From d029eaeb574c527a4a98b7db5d673a0f9638c10b Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Wed, 12 Aug 2009 07:14:02 -0700 Subject: [PATCH 1/8] 6870706: langtools launcher issues Reviewed-by: mcimadamore --- langtools/make/build.xml | 12 +++++++++++- langtools/src/share/bin/launcher.sh-template | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/langtools/make/build.xml b/langtools/make/build.xml index ac1b1ed5e43..c4912059752 100644 --- a/langtools/make/build.xml +++ b/langtools/make/build.xml @@ -83,6 +83,16 @@ + + + + + + @@ -397,7 +407,7 @@ - + diff --git a/langtools/src/share/bin/launcher.sh-template b/langtools/src/share/bin/launcher.sh-template index 3813678395a..c62af2e9b94 100644 --- a/langtools/src/share/bin/launcher.sh-template +++ b/langtools/src/share/bin/launcher.sh-template @@ -45,7 +45,7 @@ if [ "$LANGTOOLS_USE_BOOTCLASSPATH" != "no" ]; then fi # tools currently assumes that assertions are enabled in the launcher -ea=-ea:com.sun.tools +ea=-ea:com.sun.tools... # Any parameters starting with -J are passed to the JVM. # All other parameters become parameters of #PROGRAM#. From b95303097db2a4f3fe824fd7fe6552eb026ccb9c Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Wed, 12 Aug 2009 07:54:30 -0700 Subject: [PATCH 2/8] 6758471: should be able to set jtreg options in langtools build Reviewed-by: mcimadamore --- langtools/make/build.properties | 73 ++++++----- langtools/make/build.xml | 222 ++++++++++++++++---------------- 2 files changed, 154 insertions(+), 141 deletions(-) diff --git a/langtools/make/build.properties b/langtools/make/build.properties index dad12295f3c..ffe6fc0ce85 100644 --- a/langtools/make/build.properties +++ b/langtools/make/build.properties @@ -26,10 +26,10 @@ # This is the JDK used to build and run the bootstrap version of javac. # The bootstrap javac is used to compile both boostrap versions of the # other tools, and product versions of all the tools. -# Override this path as needed, either on the command line or in +# Override this path as needed, either on the command line or in # one of the standard user build.properties files (see build.xml) -# boot.java.home = /opt/jdk/1.6.0 +# boot.java.home = /opt/jdk/1.6.0 boot.java = ${boot.java.home}/bin/java boot.javac = ${boot.java.home}/bin/javac boot.javac.source = 6 @@ -37,7 +37,7 @@ boot.javac.target = 6 # This is the JDK used to run the product version of the tools, # for example, for testing. If you're building a complete JDK, specify that. -# Override this path as needed, either on the command line or in +# Override this path as needed, either on the command line or in # one of the standard user build.properties files (see build.xml) # target.java.home = /opt/jdk/1.7.0 @@ -66,23 +66,23 @@ javac.debug = true javac.debuglevel = source,lines javac.no.jdk.warnings = -XDignore.symbol.file=true # set the following to -version to verify the versions of javac being used -javac.version.opt = +javac.version.opt = # in time, there should be no exceptions to -Xlint:all javac.lint.opts = -Xlint:all,-deprecation -Werror # options for the task for javac javadoc.jls3.url=http://java.sun.com/docs/books/jls/ -javadoc.jls3.cite=<a href="${javadoc.jls3.url}">The Java Language Specification, Third Edition</a> +javadoc.jls3.cite=<a href="${javadoc.jls3.url}">The Java Language Specification, Third Edition</a> javadoc.jls3.option=-tag "jls3:a:See <cite>${javadoc.jls3.cite}</cite>:" # jtreg, used to run the JDK regression tests -# Override this path as needed, either on the command line or in +# Override this path as needed, either on the command line or in # one of the standard user build.properties files (see build.xml) # jtreg.home = /opt/jtreg/3.2.2_02 # findbugs -# Override this path as needed, either on the command line or in +# Override this path as needed, either on the command line or in # one of the standard user build.properties files (see build.xml) # findbugs.home = /opt/findbugs/1.2.1 @@ -94,46 +94,61 @@ javadoc.jls3.option=-tag "jls3:a:See <cite>${javadoc.jls3.cite}</cite&g # parameter of Ant filesets. In particular, note the trailing '/'. javac.includes = \ - javax/annotation/processing/ \ - javax/lang/model/ \ - javax/tools/ \ - com/sun/source/ com/sun/tools/javac/ + javax/annotation/processing/ \ + javax/lang/model/ \ + javax/tools/ \ + com/sun/source/ com/sun/tools/javac/ javac.tests = \ - tools/javac - + tools/javac + +# + javadoc.includes = \ - com/sun/javadoc/ \ - com/sun/tools/javadoc/ + com/sun/javadoc/ \ + com/sun/tools/javadoc/ javadoc.tests = \ - tools/javadoc/ - + tools/javadoc/ + +# + doclets.includes = \ - com/sun/tools/doclets/ + com/sun/tools/doclets/ doclets.tests = \ - com/sun/javadoc/ + com/sun/javadoc/ + +# javah.includes = \ - com/sun/tools/javah/ + com/sun/tools/javah/ javah.tests = \ - tools/javah/ + tools/javah/ + +# javap.includes = \ - com/sun/tools/classfile/ \ - com/sun/tools/javap/ \ - sun/tools/javap/ + com/sun/tools/classfile/ \ + com/sun/tools/javap/ \ + sun/tools/javap/ javap.tests = \ - tools/javap/ + tools/javap/ + +# apt.includes = \ - com/sun/mirror/ \ - com/sun/tools/apt/ + com/sun/mirror/ \ + com/sun/tools/apt/ apt.tests = \ - tools/apt/ - + tools/apt/ +# + +# The following value is used by the main jtreg target. +# An empty value means all tests +# Override as desired to run a specific set of tests +jtreg.tests = diff --git a/langtools/make/build.xml b/langtools/make/build.xml index c4912059752..e6d8524dac8 100644 --- a/langtools/make/build.xml +++ b/langtools/make/build.xml @@ -31,7 +31,7 @@ --> - + @@ -49,8 +49,8 @@ - - + + @@ -75,25 +75,25 @@ The best file to check for across Solaris/Linux/Windows/MacOS is one of the executables; regrettably, that is OS-specific. --> - + - + - + - + - - + the tools' jar files. If it has not already been set, then + default it to use ${target.java.home}, if available, otherwise + quietly default to simply use "java". --> + + - + @@ -107,13 +107,13 @@ - + - + - + - + @@ -122,13 +122,11 @@ - - - - + + + + @@ -170,52 +168,52 @@ - - + - - - + - + - + - + - + - + - + - + - + @@ -223,31 +221,31 @@ includes="${javadoc.includes}" jarclasspath="javac.jar doclets.jar"/> - + - + - + - + - + - + - + - + @@ -256,11 +254,11 @@ jarmainclass="com.sun.tools.javadoc.Main" jarclasspath="javadoc.jar"/> - + - + - + - + - + - + - + @@ -287,29 +285,29 @@ includes="${javah.includes}" jarclasspath="javadoc.jar doclets.jar javac.jar"/> - + - + - + - + - + - + - + @@ -317,85 +315,85 @@ includes="${javap.includes}" jarmainclass="sun.tools.javap.Main"/> - + - + - + - + - + - + - + - + - + - + - + - - + + - + - + - + - + - + - + - + - + - + @@ -435,8 +433,8 @@ - - + + @@ -477,7 +475,7 @@ - + @@ -540,7 +538,7 @@ includeAntRuntime="no" source="@{javac.source}" target="@{javac.target}" - debug="${javac.debug}" + debug="${javac.debug}" debuglevel="${javac.debuglevel}"> @@ -549,7 +547,7 @@ - + @@ -560,7 +558,7 @@ - + - + - + - + @@ -614,14 +612,14 @@ -
Unofficial Javadoc generated from developer sources for preview purposes only]]>
@@ -650,8 +648,8 @@
- - + + @@ -662,7 +660,7 @@ - + @@ -670,9 +668,9 @@ - - @@ -701,9 +699,9 @@ - + - + @@ -716,7 +714,7 @@ - - + @@ -763,7 +761,7 @@ - ant.home = ${ant.home} boot.java.home = ${boot.java.home} @@ -779,15 +777,15 @@ - - +
From b81f0f8916b0b109afd3656d4b84027c1862b63b Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Wed, 12 Aug 2009 10:34:13 -0700 Subject: [PATCH 3/8] 6558476: com/sun/tools/javac/Main.compile don't release file handles on return Reviewed-by: darcy --- .../javac/file/CloseableURLClassLoader.java | 105 ++++++++++++++++++ .../tools/javac/file/JavacFileManager.java | 40 ++++++- .../sun/tools/javac/main/JavaCompiler.java | 23 ++-- .../JavacProcessingEnvironment.java | 12 +- langtools/test/tools/javac/T6558476.java | 101 +++++++++++++++++ 5 files changed, 268 insertions(+), 13 deletions(-) create mode 100644 langtools/src/share/classes/com/sun/tools/javac/file/CloseableURLClassLoader.java create mode 100644 langtools/test/tools/javac/T6558476.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/file/CloseableURLClassLoader.java b/langtools/src/share/classes/com/sun/tools/javac/file/CloseableURLClassLoader.java new file mode 100644 index 00000000000..a88a32cb097 --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/javac/file/CloseableURLClassLoader.java @@ -0,0 +1,105 @@ +/* + * Copyright 2007 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * 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. + */ + +package com.sun.tools.javac.file; + +import java.io.Closeable; +import java.io.IOException; +import java.lang.reflect.Field; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.jar.JarFile; + +/** + * A URLClassLoader that also implements Closeable. + * Reflection is used to access internal data structures in the URLClassLoader, + * since no public API exists for this purpose. Therefore this code is somewhat + * fragile. Caveat emptor. + * @throws Error if the internal data structures are not as expected. + * + *

This is NOT part of any API supported by Sun Microsystems. If + * you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + */ +class CloseableURLClassLoader + extends URLClassLoader implements Closeable { + CloseableURLClassLoader(URL[] urls, ClassLoader parent) throws Error { + super(urls, parent); + try { + getLoaders(); //proactive check that URLClassLoader is as expected + } catch (Throwable t) { + throw new Error("cannot create CloseableURLClassLoader", t); + } + } + + /** + * Close any jar files that may have been opened by the class loader. + * Reflection is used to access the jar files in the URLClassLoader's + * internal data structures. + * @throws java.io.IOException if the jar files cannot be found for any + * reson, or if closing the jar file itself causes an IOException. + */ + public void close() throws IOException { + try { + for (Object l: getLoaders()) { + if (l.getClass().getName().equals("sun.misc.URLClassPath$JarLoader")) { + Field jarField = l.getClass().getDeclaredField("jar"); + JarFile jar = (JarFile) getField(l, jarField); + //System.err.println("CloseableURLClassLoader: closing " + jar); + jar.close(); + } + } + } catch (Throwable t) { + IOException e = new IOException("cannot close class loader"); + e.initCause(t); + throw e; + } + } + + private ArrayList getLoaders() + throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException + { + Field ucpField = URLClassLoader.class.getDeclaredField("ucp"); + Object urlClassPath = getField(this, ucpField); + if (urlClassPath == null) + throw new AssertionError("urlClassPath not set in URLClassLoader"); + Field loadersField = urlClassPath.getClass().getDeclaredField("loaders"); + return (ArrayList) getField(urlClassPath, loadersField); + } + + private Object getField(Object o, Field f) + throws IllegalArgumentException, IllegalAccessException { + boolean prev = f.isAccessible(); + try { + f.setAccessible(true); + return f.get(o); + } finally { + f.setAccessible(prev); + } + } + +} diff --git a/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java b/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java index 3ea1978b3ef..15a22400f6b 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java +++ b/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java @@ -33,6 +33,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.lang.ref.SoftReference; +import java.lang.reflect.Constructor; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; @@ -76,6 +77,7 @@ import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.Log; import com.sun.tools.javac.util.Options; +import java.io.Closeable; import static javax.tools.StandardLocation.*; import static com.sun.tools.javac.main.OptionName.*; @@ -131,6 +133,7 @@ public class JavacFileManager implements StandardJavaFileManager { protected boolean mmappedIO; protected boolean ignoreSymbolFile; + protected String classLoaderClass; /** * User provided charset (through javax.tools). @@ -180,6 +183,7 @@ public class JavacFileManager implements StandardJavaFileManager { mmappedIO = options.get("mmappedIO") != null; ignoreSymbolFile = options.get("ignore.symbol.file") != null; + classLoaderClass = options.get("procloader"); } public JavaFileObject getFileForInput(String name) { @@ -747,8 +751,40 @@ public class JavacFileManager implements StandardJavaFileManager { throw new AssertionError(e); } } - return new URLClassLoader(lb.toArray(new URL[lb.size()]), - getClass().getClassLoader()); + + URL[] urls = lb.toArray(new URL[lb.size()]); + ClassLoader thisClassLoader = getClass().getClassLoader(); + + // Bug: 6558476 + // Ideally, ClassLoader should be Closeable, but before JDK7 it is not. + // On older versions, try the following, to get a closeable classloader. + + // 1: Allow client to specify the class to use via hidden option + if (classLoaderClass != null) { + try { + Class loader = + Class.forName(classLoaderClass).asSubclass(ClassLoader.class); + Class[] constrArgTypes = { URL[].class, ClassLoader.class }; + Constructor constr = loader.getConstructor(constrArgTypes); + return constr.newInstance(new Object[] { urls, thisClassLoader }); + } catch (Throwable t) { + // ignore errors loading user-provided class loader, fall through + } + } + + // 2: If URLClassLoader implements Closeable, use that. + if (Closeable.class.isAssignableFrom(URLClassLoader.class)) + return new URLClassLoader(urls, thisClassLoader); + + // 3: Try using private reflection-based CloseableURLClassLoader + try { + return new CloseableURLClassLoader(urls, thisClassLoader); + } catch (Throwable t) { + // ignore errors loading workaround class loader, fall through + } + + // 4: If all else fails, use plain old standard URLClassLoader + return new URLClassLoader(urls, thisClassLoader); } public Iterable list(Location location, diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java index e93d82fdaa7..d9f55c23ea9 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java +++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java @@ -813,6 +813,9 @@ public class JavaCompiler implements ClassReader.SourceCompleter { } catch (Abort ex) { if (devVerbose) ex.printStackTrace(); + } finally { + if (procEnvImpl != null) + procEnvImpl.close(); } } @@ -936,7 +939,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter { /** * Object to handle annotation processing. */ - JavacProcessingEnvironment procEnvImpl = null; + private JavacProcessingEnvironment procEnvImpl = null; /** * Check if we should process annotations. @@ -947,7 +950,8 @@ public class JavaCompiler implements ClassReader.SourceCompleter { * @param processors user provided annotation processors to bypass * discovery, {@code null} means that no processors were provided */ - public void initProcessAnnotations(Iterable processors) { + public void initProcessAnnotations(Iterable processors) + throws IOException { // Process annotations if processing is not disabled and there // is at least one Processor available. Options options = Options.instance(context); @@ -974,7 +978,8 @@ public class JavaCompiler implements ClassReader.SourceCompleter { } // TODO: called by JavacTaskImpl - public JavaCompiler processAnnotations(List roots) throws IOException { + public JavaCompiler processAnnotations(List roots) + throws IOException { return processAnnotations(roots, List.nil()); } @@ -1061,10 +1066,14 @@ public class JavaCompiler implements ClassReader.SourceCompleter { return this; } } - JavaCompiler c = procEnvImpl.doProcessing(context, roots, classSymbols, pckSymbols); - if (c != this) - annotationProcessingOccurred = c.annotationProcessingOccurred = true; - return c; + try { + JavaCompiler c = procEnvImpl.doProcessing(context, roots, classSymbols, pckSymbols); + if (c != this) + annotationProcessingOccurred = c.annotationProcessingOccurred = true; + return c; + } finally { + procEnvImpl.close(); + } } catch (CompletionFailure ex) { log.error("cant.access", ex.sym, ex.getDetailValue()); return this; diff --git a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java index dd21d41a14f..8c64d424b0e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java +++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java @@ -136,6 +136,8 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea */ Source source; + private ClassLoader processorClassLoader; + /** * JavacMessages object used for localization */ @@ -203,7 +205,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea JavaFileManager fileManager = context.get(JavaFileManager.class); try { // If processorpath is not explicitly set, use the classpath. - ClassLoader processorCL = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH) + processorClassLoader = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH) ? fileManager.getClassLoader(ANNOTATION_PROCESSOR_PATH) : fileManager.getClassLoader(CLASS_PATH); @@ -213,9 +215,9 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea * provider mechanism to create the processor iterator. */ if (processorNames != null) { - processorIterator = new NameProcessIterator(processorNames, processorCL, log); + processorIterator = new NameProcessIterator(processorNames, processorClassLoader, log); } else { - processorIterator = new ServiceIterator(processorCL, log); + processorIterator = new ServiceIterator(processorClassLoader, log); } } catch (SecurityException e) { /* @@ -1019,9 +1021,11 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea /** * Free resources related to annotation processing. */ - public void close() { + public void close() throws IOException { filer.close(); discoveredProcs = null; + if (processorClassLoader != null && processorClassLoader instanceof Closeable) + ((Closeable) processorClassLoader).close(); } private List getTopLevelClasses(List units) { diff --git a/langtools/test/tools/javac/T6558476.java b/langtools/test/tools/javac/T6558476.java new file mode 100644 index 00000000000..7286128dcb7 --- /dev/null +++ b/langtools/test/tools/javac/T6558476.java @@ -0,0 +1,101 @@ +/* + * Copyright 2008 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 + * @run main/othervm -Xmx512m -Xms512m T6558476 + */ + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Random; + +import com.sun.tools.javac.Main; + +public class T6558476 { + private static File copyFileTo(File file, File directory) throws IOException { + File newFile = new File(directory, file.getName()); + FileInputStream fis = null; + FileOutputStream fos = null; + try { + fis = new FileInputStream(file); + fos = new FileOutputStream(newFile); + byte buff[] = new byte[1024]; + int val; + while ((val = fis.read(buff)) > 0) + fos.write(buff, 0, val); + } finally { + if (fis != null) + fis.close(); + if (fos != null) + fos.close(); + } + return newFile; + } + + private static String generateJavaClass(String className) { + StringBuffer sb = new StringBuffer(); + sb.append("import sun.net.spi.nameservice.dns.DNSNameService;\n"); + sb.append("public class "); + sb.append(className); + sb.append(" {\n"); + sb.append(" public void doStuff() {\n"); + sb.append(" DNSNameService dns = null;\n"); + sb.append(" }\n"); + sb.append("}\n"); + return sb.toString(); + } + + public static void main(String[] args) throws IOException { + File javaHomeDir = new File(System.getProperty("java.home")); + File tmpDir = new File(System.getProperty("java.io.tmpdir")); + File outputDir = new File(tmpDir, "outputDir" + new Random().nextInt(65536)); + outputDir.mkdir(); + outputDir.deleteOnExit(); + + File dnsjarfile = new File(javaHomeDir, "lib" + File.separator + "ext" + File.separator + "dnsns.jar"); + File tmpJar = copyFileTo(dnsjarfile, outputDir); + String className = "TheJavaFile"; + File javaFile = new File(outputDir, className + ".java"); + javaFile.deleteOnExit(); + FileOutputStream fos = new FileOutputStream(javaFile); + fos.write(generateJavaClass(className).getBytes()); + fos.close(); + + int rc = Main.compile(new String[]{"-d", outputDir.getPath(), + "-classpath", + tmpJar.getPath(), + javaFile.getAbsolutePath()}); + if (rc != 0) { + throw new Error("Couldn't compile the file (exit code=" + rc + ")"); + } + + if (tmpJar.delete()) { + System.out.println("jar file successfully deleted"); + } else { + throw new Error("Error deleting file \"" + tmpJar.getPath() + "\""); + } + } +} From 5c818e4b6af16497892f199bcbd256add34a727e Mon Sep 17 00:00:00 2001 From: Andrew John Hughes Date: Wed, 19 Aug 2009 20:44:22 +0100 Subject: [PATCH 4/8] 6873059: Explicitly use -source 6 -target 6 when compiling with the boot jdk Set source and target explicitly in pcompile task Reviewed-by: jjg --- langtools/make/build.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/langtools/make/build.xml b/langtools/make/build.xml index e6d8524dac8..30d63801cf1 100644 --- a/langtools/make/build.xml +++ b/langtools/make/build.xml @@ -592,6 +592,8 @@ Date: Wed, 19 Aug 2009 17:12:36 -0700 Subject: [PATCH 5/8] 6871291: Please clarify javax.tools.JavaCompiler.getTask() "classes" parameter Reviewed-by: jjg --- .../src/share/classes/javax/tools/JavaCompiler.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/langtools/src/share/classes/javax/tools/JavaCompiler.java b/langtools/src/share/classes/javax/tools/JavaCompiler.java index 6e8c1a69e7f..e360e0167b0 100644 --- a/langtools/src/share/classes/javax/tools/JavaCompiler.java +++ b/langtools/src/share/classes/javax/tools/JavaCompiler.java @@ -228,6 +228,12 @@ public interface JavaCompiler extends Tool, OptionChecker { *

If a file manager is provided, it must be able to handle all * locations defined in {@link StandardLocation}. * + *

Note that annotation processing can process both the + * compilation units of source code to be compiled, passed with + * the {@code compilationUnits} parameter, as well as class + * files, whose names are passed with the {@code classes} + * parameter. + * * @param out a Writer for additional output from the compiler; * use {@code System.err} if {@code null} * @param fileManager a file manager; if {@code null} use the @@ -236,8 +242,8 @@ public interface JavaCompiler extends Tool, OptionChecker { * null} use the compiler's default method for reporting * diagnostics * @param options compiler options, {@code null} means no options - * @param classes class names (for annotation processing), {@code - * null} means no class names + * @param classes names of classes to be processed by annotation + * processing, {@code null} means no class names * @param compilationUnits the compilation units to compile, {@code * null} means no compilation units * @return an object representing the compilation From bde1a2faf8ba298542f21745d1bb8d53250128ac Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Fri, 21 Aug 2009 11:25:45 -0700 Subject: [PATCH 6/8] 6873849: suppress notes generated by javac Reviewed-by: darcy --- .../classes/com/sun/tools/javac/util/Log.java | 7 +- langtools/test/tools/javac/T6873849.java | 76 +++++++++++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 langtools/test/tools/javac/T6873849.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java index d405de58224..7fd1e2fc1b5 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java @@ -78,6 +78,10 @@ public class Log extends AbstractLog { */ public boolean emitWarnings; + /** Switch: suppress note messages. + */ + public boolean suppressNotes; + /** Print stack trace on errors? */ public boolean dumpOnError; @@ -121,6 +125,7 @@ public class Log extends AbstractLog { this.dumpOnError = options.get("-doe") != null; this.promptOnError = options.get("-prompt") != null; this.emitWarnings = options.get("-Xlint:none") == null; + this.suppressNotes = options.get("suppressNotes") != null; this.MaxErrors = getIntOption(options, "-Xmaxerrs", 100); this.MaxWarnings = getIntOption(options, "-Xmaxwarns", 100); @@ -324,7 +329,7 @@ public class Log extends AbstractLog { // Print out notes only when we are permitted to report warnings // Notes are only generated at the end of a compilation, so should be small // in number. - if (emitWarnings || diagnostic.isMandatory()) { + if ((emitWarnings || diagnostic.isMandatory()) && !suppressNotes) { writeDiagnostic(diagnostic); } break; diff --git a/langtools/test/tools/javac/T6873849.java b/langtools/test/tools/javac/T6873849.java new file mode 100644 index 00000000000..67d0772e46e --- /dev/null +++ b/langtools/test/tools/javac/T6873849.java @@ -0,0 +1,76 @@ +/* + * Copyright 2006 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. + */ + +import java.io.File; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.List; + +/* + * @test + * @bug 6873849 + * @summary suppress notes generated by javac + */ + +public class T6873849 { + public static void main(String... args) throws Exception { + new T6873849().run(); + } + + public void run() throws Exception { + test(null, "- compiler.note.unchecked.filename: T6873849.java" + newline + + "- compiler.note.unchecked.recompile" + newline); + test("-XDsuppressNotes", ""); + } + + void test(String opt, String expect) throws Exception { + List args = new ArrayList(); + if (opt != null) + args.add(opt); + args.add("-d"); + args.add(testClasses.getPath()); + args.add("-XDrawDiagnostics"); + args.add(new File(testSrc, "T6873849.java").getPath()); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + System.err.println("compile: " + args); + int rc = com.sun.tools.javac.Main.compile(args.toArray(new String[args.size()]), pw); + pw.close(); + String out = sw.toString(); + System.out.println(out); + if (rc != 0) + throw new Exception("compilation failed unexpectedly"); + if (!out.equals(expect)) + throw new Exception("unexpected output from compiler"); + } + + void m(List t) { + // force a note about unchecked usage + t.add(new Object()); + } + + private File testSrc = new File(System.getProperty("test.src", ".")); + private File testClasses = new File(System.getProperty("test.classes", ".")); + private String newline = System.getProperty("line.separator"); +} From 0ec5040633006da4ae94af5995fe91b831f05f6e Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Fri, 21 Aug 2009 14:58:21 -0700 Subject: [PATCH 7/8] 6873845: refine access to symbol file Reviewed-by: darcy --- .../com/sun/tools/javac/code/Lint.java | 13 ++- .../com/sun/tools/javac/comp/Attr.java | 15 +++- .../com/sun/tools/javac/comp/Check.java | 16 ++++ .../com/sun/tools/javac/main/JavacOption.java | 43 ++++++---- .../tools/javac/main/RecognizedOptions.java | 16 ++-- .../tools/javac/resources/compiler.properties | 25 ++++-- langtools/test/tools/javac/T6873845.java | 84 +++++++++++++++++++ 7 files changed, 179 insertions(+), 33 deletions(-) create mode 100644 langtools/test/tools/javac/T6873845.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java b/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java index 8025e61b966..cec6e70a99d 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java @@ -193,10 +193,20 @@ public class Lint /** * Warn about unchecked operations on raw types. */ - RAW("rawtypes"); + RAW("rawtypes"), + + /** + * Warn about Sun proprietary API that may be removed in a future release. + */ + SUNAPI("sunapi", true); LintCategory(String option) { + this(option, false); + } + + LintCategory(String option, boolean hidden) { this.option = option; + this.hidden = hidden; map.put(option, this); } @@ -205,6 +215,7 @@ public class Lint } public final String option; + public final boolean hidden; }; /** diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index 0607e709576..cd76e77579e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -119,6 +119,7 @@ public class Attr extends JCTree.Visitor { options.get("-relax") != null); useBeforeDeclarationWarning = options.get("useBeforeDeclarationWarning") != null; allowInvokedynamic = options.get("invokedynamic") != null; + enableSunApiLintControl = options.get("enableSunApiLintControl") != null; } /** Switch: relax some constraints for retrofit mode. @@ -160,6 +161,12 @@ public class Attr extends JCTree.Visitor { */ boolean useBeforeDeclarationWarning; + /** + * Switch: allow lint infrastructure to control Sun proprietary + * API warnings. + */ + boolean enableSunApiLintControl; + /** Check kind and type of given tree against protokind and prototype. * If check succeeds, store type in tree and return it. * If check fails, store errType in tree and return it. @@ -2215,8 +2222,12 @@ public class Attr extends JCTree.Visitor { sym.outermostClass() != env.info.scope.owner.outermostClass()) chk.warnDeprecated(tree.pos(), sym); - if ((sym.flags() & PROPRIETARY) != 0) - log.strictWarning(tree.pos(), "sun.proprietary", sym); + if ((sym.flags() & PROPRIETARY) != 0) { + if (enableSunApiLintControl) + chk.warnSunApi(tree.pos(), "sun.proprietary", sym); + else + log.strictWarning(tree.pos(), "sun.proprietary", sym); + } // Test (3): if symbol is a variable, check that its type and // kind are compatible with the prototype and protokind. diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index e03596dad4d..76466ddd367 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -104,12 +104,15 @@ public class Check { boolean verboseDeprecated = lint.isEnabled(LintCategory.DEPRECATION); boolean verboseUnchecked = lint.isEnabled(LintCategory.UNCHECKED); + boolean verboseSunApi = lint.isEnabled(LintCategory.SUNAPI); boolean enforceMandatoryWarnings = source.enforceMandatoryWarnings(); deprecationHandler = new MandatoryWarningHandler(log, verboseDeprecated, enforceMandatoryWarnings, "deprecated"); uncheckedHandler = new MandatoryWarningHandler(log, verboseUnchecked, enforceMandatoryWarnings, "unchecked"); + sunApiHandler = new MandatoryWarningHandler(log, verboseSunApi, + enforceMandatoryWarnings, "sunapi"); } /** Switch: generics enabled? @@ -137,6 +140,9 @@ public class Check { */ private MandatoryWarningHandler uncheckedHandler; + /** A handler for messages about using Sun proprietary API. + */ + private MandatoryWarningHandler sunApiHandler; /* ************************************************************************* * Errors and Warnings @@ -166,12 +172,22 @@ public class Check { uncheckedHandler.report(pos, msg, args); } + /** Warn about using Sun proprietary API. + * @param pos Position to be used for error reporting. + * @param msg A string describing the problem. + */ + public void warnSunApi(DiagnosticPosition pos, String msg, Object... args) { + if (!lint.isSuppressed(LintCategory.SUNAPI)) + sunApiHandler.report(pos, msg, args); + } + /** * Report any deferred diagnostics. */ public void reportDeferredDiagnostics() { deprecationHandler.reportDeferredDiagnostic(); uncheckedHandler.reportDeferredDiagnostic(); + sunApiHandler.reportDeferredDiagnostic(); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/JavacOption.java b/langtools/src/share/classes/com/sun/tools/javac/main/JavacOption.java index 189d3c555d2..2b8a915cf01 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/main/JavacOption.java +++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavacOption.java @@ -25,11 +25,11 @@ package com.sun.tools.javac.main; +import java.io.PrintWriter; +import java.util.LinkedHashMap; +import java.util.Map; import com.sun.tools.javac.util.Log; import com.sun.tools.javac.util.Options; -import java.io.PrintWriter; -import java.util.Arrays; -import java.util.Collection; /** * TODO: describe com.sun.tools.javac.main.JavacOption @@ -106,9 +106,10 @@ public interface JavacOption { */ ChoiceKind choiceKind; - /** The choices for this option, if any. + /** The choices for this option, if any, and whether or not the choices + * are hidden */ - Collection choices; + Map choices; Option(OptionName name, String argsNameKey, String descrKey) { this.name = name; @@ -123,10 +124,18 @@ public interface JavacOption { } Option(OptionName name, String descrKey, ChoiceKind choiceKind, String... choices) { - this(name, descrKey, choiceKind, Arrays.asList(choices)); + this(name, descrKey, choiceKind, createChoices(choices)); } - Option(OptionName name, String descrKey, ChoiceKind choiceKind, Collection choices) { + private static Map createChoices(String... choices) { + Map map = new LinkedHashMap(); + for (String c: choices) + map.put(c, true); + return map; + } + + Option(OptionName name, String descrKey, ChoiceKind choiceKind, + Map choices) { this(name, null, descrKey); if (choiceKind == null || choices == null) throw new NullPointerException(); @@ -153,10 +162,10 @@ public interface JavacOption { if (choices != null) { String arg = option.substring(name.optionName.length()); if (choiceKind == ChoiceKind.ONEOF) - return choices.contains(arg); + return choices.keySet().contains(arg); else { for (String a: arg.split(",+")) { - if (!choices.contains(a)) + if (!choices.keySet().contains(a)) return false; } } @@ -181,10 +190,12 @@ public interface JavacOption { if (argsNameKey == null) { if (choices != null) { String sep = "{"; - for (String c: choices) { - sb.append(sep); - sb.append(c); - sep = ","; + for (Map.Entry e: choices.entrySet()) { + if (!e.getValue()) { + sb.append(sep); + sb.append(e.getKey()); + sep = ","; + } } sb.append("}"); } @@ -209,8 +220,8 @@ public interface JavacOption { if (choices != null) { if (choiceKind == ChoiceKind.ONEOF) { // some clients like to see just one of option+choice set - for (String c: choices) - options.remove(option + c); + for (String s: choices.keySet()) + options.remove(option + s); String opt = option + arg; options.put(opt, opt); // some clients like to see option (without trailing ":") @@ -256,7 +267,7 @@ public interface JavacOption { XOption(OptionName name, String descrKey, ChoiceKind kind, String... choices) { super(name, descrKey, kind, choices); } - XOption(OptionName name, String descrKey, ChoiceKind kind, Collection choices) { + XOption(OptionName name, String descrKey, ChoiceKind kind, Map choices) { super(name, descrKey, kind, choices); } @Override diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/RecognizedOptions.java b/langtools/src/share/classes/com/sun/tools/javac/main/RecognizedOptions.java index 8e0eb888f31..885767f68c0 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/main/RecognizedOptions.java +++ b/langtools/src/share/classes/com/sun/tools/javac/main/RecognizedOptions.java @@ -38,9 +38,9 @@ import com.sun.tools.javac.processing.JavacProcessingEnvironment; import java.io.File; import java.io.FileWriter; import java.io.PrintWriter; -import java.util.Collection; import java.util.EnumSet; -import java.util.LinkedHashSet; +import java.util.LinkedHashMap; +import java.util.Map; import java.util.Set; import javax.lang.model.SourceVersion; @@ -598,14 +598,14 @@ public class RecognizedOptions { }; } - private static Collection getXLintChoices() { - Collection choices = new LinkedHashSet(); - choices.add("all"); + private static Map getXLintChoices() { + Map choices = new LinkedHashMap(); + choices.put("all", false); for (Lint.LintCategory c : Lint.LintCategory.values()) - choices.add(c.option); + choices.put(c.option, c.hidden); for (Lint.LintCategory c : Lint.LintCategory.values()) - choices.add("-" + c.option); - choices.add("none"); + choices.put("-" + c.option, c.hidden); + choices.put("none", false); return choices; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties index c3a10da3941..78324242d60 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -564,12 +564,6 @@ compiler.note.deprecated.filename.additional=\ compiler.note.deprecated.plural.additional=\ Some input files additionally use or override a deprecated API. -# Notes related to annotation processing - -# Print a client-generated note; assumed to be localized, no translation required -compiler.note.proc.messager=\ - {0} - compiler.note.unchecked.filename=\ {0} uses unchecked or unsafe operations. compiler.note.unchecked.plural=\ @@ -584,6 +578,25 @@ compiler.note.unchecked.filename.additional=\ compiler.note.unchecked.plural.additional=\ Some input files additionally use unchecked or unsafe operations. +compiler.note.sunapi.filename=\ + {0} uses Sun proprietary API that may be removed in a future release. +compiler.note.sunapi.plural=\ + Some input files use Sun proprietary API that may be removed in a future release. +# The following string may appear after one of the above sunapi messages. +compiler.note.sunapi.recompile=\ + Recompile with -Xlint:sunapi for details. + +compiler.note.sunapi.filename.additional=\ + {0} uses additional Sun proprietary API that may be removed in a future release. +compiler.note.sunapi.plural.additional=\ + Some input files additionally use Sun proprietary API that may be removed in a future release. + +# Notes related to annotation processing + +# Print a client-generated note; assumed to be localized, no translation required +compiler.note.proc.messager=\ + {0} + ##### compiler.misc.count.error=\ diff --git a/langtools/test/tools/javac/T6873845.java b/langtools/test/tools/javac/T6873845.java new file mode 100644 index 00000000000..ff84028326f --- /dev/null +++ b/langtools/test/tools/javac/T6873845.java @@ -0,0 +1,84 @@ +import java.io.*; +import java.util.*; + +import sun.misc.*; + +/* + * @test /nodynamiccopyright/ + * @bug 6873845 + * @summary refine access to symbol file + */ + +public class T6873845 { + public static void main(String... args) throws Exception { + new T6873845().run(); + } + + public void run() throws Exception { + String out = compile(Arrays.asList("-XDrawDiagnostics", "-X")); + if (out.contains("sunapi")) + throw new Exception("unexpected output for -X"); + + String warn1 = "T6873845.java:72:9: compiler.warn.sun.proprietary: sun.misc.Unsafe" + newline; + String warn2 = "T6873845.java:77:9: compiler.warn.sun.proprietary: sun.misc.Unsafe" + newline; + String note1 = "- compiler.note.sunapi.filename: T6873845.java" + newline; + String note2 = "- compiler.note.sunapi.recompile" + newline; + + test(opts(), + warn1 + warn2 + "2 warnings" + newline); + test(opts("-XDenableSunApiLintControl"), + note1 + note2); + test(opts("-XDenableSunApiLintControl", "-XDsuppressNotes"), + ""); + test(opts("-XDenableSunApiLintControl", "-Xlint:sunapi"), + warn1 + "1 warning" + newline); + test(opts("-XDenableSunApiLintControl", "-Xlint:all"), + warn1 + "1 warning" + newline); + test(opts("-XDenableSunApiLintControl", "-Xlint:all,-sunapi"), + note1 + note2); + } + + List opts(String... opts) { + return Arrays.asList(opts); + } + + void test(List opts, String expect) throws Exception { + List args = new ArrayList(); + args.addAll(opts); + args.add("-d"); + args.add(testClasses.getPath()); + args.add(new File(testSrc, "T6873845.java").getPath()); + compile(args); // to verify resource strings exist + args.add(0, "-XDrawDiagnostics"); + String out = compile(args); + if (!out.equals(expect)) + throw new Exception("unexpected output from compiler"); + } + + String compile(List args) throws Exception{ + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + System.out.println("compile: " + args); + int rc = com.sun.tools.javac.Main.compile(args.toArray(new String[args.size()]), pw); + pw.close(); + String out = sw.toString(); + System.out.println(out); + if (rc != 0) + throw new Exception("compilation failed unexpectedly"); + return out; + } + + void m1() { + Unsafe.getUnsafe(); + } + + @SuppressWarnings("sunapi") + void m2() { + Unsafe.getUnsafe(); + } + + private File testSrc = new File(System.getProperty("test.src", ".")); + private File testClasses = new File(System.getProperty("test.classes", ".")); + private String newline = System.getProperty("line.separator"); +} + From b91de4eb6a0f92c8e419510e7350dc6080059ab5 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 24 Aug 2009 14:38:42 -0700 Subject: [PATCH 8/8] 6869216: testgetallmembers should consistently use correct filemanager Reviewed-by: darcy --- .../tools/javac/processing/model/testgetallmembers/Main.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langtools/test/tools/javac/processing/model/testgetallmembers/Main.java b/langtools/test/tools/javac/processing/model/testgetallmembers/Main.java index 6cb584a084b..f2e47d393ee 100644 --- a/langtools/test/tools/javac/processing/model/testgetallmembers/Main.java +++ b/langtools/test/tools/javac/processing/model/testgetallmembers/Main.java @@ -95,7 +95,7 @@ public class Main { javac = null; elements = null; - javac = (JavacTask)tool.getTask(null, null, null, null, null, null); + javac = (JavacTask)tool.getTask(null, fm, null, null, null, null); elements = javac.getElements(); for (String name : packages) {