JDK-6548708 : Annotation processing should free service loader if there are no processors
  • Type: Bug
  • Component: core-libs
  • Sub-Component: javax.annotation.processing
  • Affected Version: 7
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2007-04-20
  • Updated: 2011-07-15
  • Resolved: 2011-07-15
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7 b72Fixed
Related Reports
Relates :  
Description
The annotation processing system uses a service loader to look for annotation processors.  This can involve holding open jar files, etc.  However, if there are no processors actually available (the common case at the moment) the resources associated with the service loader should be able to be freed.  The implementation of annotation processing in javac does not currently free the service loader if no processors are found.

Comments
PUBLIC COMMENTS See http://hg.openjdk.java.net/jdk7/tl/langtools/rev/25f15fdd168a
27-08-2009

SUGGESTED FIX # HG changeset patch # User darcy # Date 1251340131 25200 # Node ID 25f15fdd168a254a49b143c14156059e95986621 # Parent 40aca381dcaf80433c1b046ffca0f883aed90a58 6548708: Annotation processing should free service loader if there are no processors Reviewed-by: jjg --- a/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Tue Aug 25 16:41:32 2009 -0700 +++ b/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Wed Aug 26 19:28:51 2009 -0700 @@ -287,11 +287,12 @@ public class JavacProcessingEnvironment // 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 @@ public class JavacProcessingEnvironment // 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(); } @@ -364,6 +366,18 @@ public class JavacProcessingEnvironment 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 @@ public class JavacProcessingEnvironment * 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<ProcessorState> { @@ -623,6 +637,16 @@ public class JavacProcessingEnvironment DiscoveredProcessors(Iterator<? extends Processor> processorIterator) { this.processorIterator = processorIterator; this.procStateList = new ArrayList<ProcessorState>(); + } + + /** + * Free jar files, etc. if using a service loader. + */ + public void close() { + if (processorIterator != null && + processorIterator instanceof ServiceIterator) { + ((ServiceIterator) processorIterator).close(); + } } } @@ -910,7 +934,7 @@ public class JavacProcessingEnvironment * 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 class JavacProcessingEnvironment */ 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();
27-08-2009

EVALUATION Should be fixed.
20-04-2007