--- old/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java 2009-08-26 19:29:03.000000000 -0700 +++ new/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java 2009-08-26 19:29:03.000000000 -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();