# HG changeset patch # User darcy # Date 1251340131 25200 # Node ID f0077f1659832b1f4f81f3f5a00d5a585e01e0c1 # Parent be9e8bdd7eaded6b351ebe020d5b3b8cacf04509 6548708: Annotation processing should free service loader if there are no processors Reviewed-by: jjg diff -r be9e8bdd7ead -r f0077f165983 langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java --- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Tue Aug 25 16:41:32 2009 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Wed Aug 26 19:28:51 2009 -0700 @@ -287,11 +287,12 @@ // The to-be-wrapped iterator. private Iterator iterator; private Log log; + private Class loaderClass; + private boolean jusl; + private Object loader; ServiceIterator(ClassLoader classLoader, Log log) { - Class loaderClass; String loadMethodName; - boolean jusl; this.log = log; try { @@ -324,6 +325,7 @@ // For java.util.ServiceLoader, we have to call another // method to get the iterator. if (jusl) { + loader = result; // Store ServiceLoader to call reload later Method m = loaderClass.getMethod("iterator"); result = m.invoke(result); // serviceLoader.iterator(); } @@ -365,6 +367,18 @@ public void remove() { throw new UnsupportedOperationException(); } + + public void close() { + if (jusl) { + try { + // Call java.util.ServiceLoader.reload + Method reloadMethod = loaderClass.getMethod("reload"); + reloadMethod.invoke(loader); + } catch(Exception e) { + ; // Ignore problems during a call to reload. + } + } + } } @@ -552,7 +566,7 @@ * been discoverd so far as well as the means to discover more, if * necessary. A single iterator should be used per round of * annotation processing. The iterator first visits already - * discovered processors then fails over to the service provided + * discovered processors then fails over to the service provider * mechanism if additional queries are made. */ class DiscoveredProcessors implements Iterable { @@ -624,6 +638,16 @@ this.processorIterator = processorIterator; this.procStateList = new ArrayList(); } + + /** + * Free jar files, etc. if using a service loader. + */ + public void close() { + if (processorIterator != null && + processorIterator instanceof ServiceIterator) { + ((ServiceIterator) processorIterator).close(); + } + } } private void discoverAndRunProcs(Context context, @@ -910,7 +934,7 @@ * second to last round; errorRaised() gives the error status * of the last round. */ - errorStatus = errorStatus || messager.errorRaised(); + errorStatus = errorStatus || messager.errorRaised(); // Free resources @@ -1023,6 +1047,8 @@ */ public void close() throws IOException { filer.close(); + if (discoveredProcs != null) // Make calling close idempotent + discoveredProcs.close(); discoveredProcs = null; if (processorClassLoader != null && processorClassLoader instanceof Closeable) ((Closeable) processorClassLoader).close();