JDK-5048534 : apt should allow annotation processor factories to record static state
  • Type: Bug
  • Component: tools
  • Sub-Component: apt
  • Affected Version: 5.0
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2004-05-17
  • Updated: 2017-05-16
  • Resolved: 2004-06-17
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.
Other
5.0 b57Fixed
Related Reports
Relates :  
Relates :  
Description
As currently written, the apt tool uses a new classloader for each round of apt processing.  Consequently, "the same" class is loaded multiple times and factory class cannot use static state inside itself to determine what to do.  Factories should be able to use such state.

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: tiger-rc FIXED IN: tiger-rc INTEGRATED IN: tiger-b57 tiger-rc
25-06-2004

SUGGESTED FIX src/share/classes/com/sun/tools/apt/main>sccs sccsdiff -r1.11 -r1.12 Main.java ------- Main.java ------- 21a22 > import java.util.Collection; 22a24,28 > import java.net.URLClassLoader; > import java.net.URL; > import java.io.File; > import java.net.MalformedURLException; > 60a67,70 > /** Classloader to use for finding factories. > */ > ClassLoader aptCL = null; > 427c437 < new AptXOption("-XPrintAptInvocations", "opt.XPrintAptInvocations"), --- > new AptXOption("-XPrintAptRounds", "opt.XPrintAptRounds"), 739a750 > String baseClassPath = ""; 776,777c787,788 < augmentedClassPath += (s + File.pathSeparator); < // put augmentedClassPath into map to handle any --- > baseClassPath += (s + File.pathSeparator); > // put baseClassPath into map to handle any 779c790 < options.put("-classpath", augmentedClassPath); --- > options.put("-classpath", baseClassPath); 781c792 < augmentedClassPath += (classDest == null)?".":classDest; --- > augmentedClassPath = baseClassPath + ((classDest == null)?".":classDest); 783c794 < augmentedClassPath = "."; --- > baseClassPath = "."; 785c796 < augmentedClassPath += (File.pathSeparator + classDest); --- > augmentedClassPath = baseClassPath + (File.pathSeparator + classDest); 790c801,842 < int run = 0; // For -XPrintAptInvocations --- > /* > * Create base and augmented class loaders > */ > ClassLoader augmentedAptCL = null; > { > /* > * Use a url class loader to look for classes on the > * user-specified class path. Prepend computed bootclass > * path, which includes extdirs, to the URLClassLoader apt > * uses. > */ > String aptclasspath = ""; > Paths paths = Paths.instance(context); > String bcp = ""; > Collection<String> bootclasspath = paths.bootClassPath(); > > if (bootclasspath != null) { > for(String s: bootclasspath) > bcp += (s + File.pathSeparator); > } > > // If the factory path is set, use that path > aptclasspath = options.get("-factorypath"); > if (aptclasspath == null) > aptclasspath = options.get("-classpath"); > > assert aptclasspath != null; > aptclasspath = (bcp + aptclasspath); > aptCL = new URLClassLoader(pathToURLs(aptclasspath)); > > if (options.get("-factorypath") != null) // same CL even if new class files written > augmentedAptCL = aptCL; > else { > // Create class loader in case new class files are > // written > augmentedAptCL = new URLClassLoader(pathToURLs(augmentedClassPath. > substring(baseClassPath.length())), > aptCL); > } > } > > int run = 0; // For -XPrintAptRounds 812a865 > aptCL = augmentedAptCL; 819c872 < if (options.get("-XPrintAptInvocations") != null) { --- > if (options.get("-XPrintAptRounds") != null) { 941c994,995 < origOptions); --- > origOptions, > aptCL); 1087a1142,1196 > > // Borrowed from DocletInvoker > /** > * Utility method for converting a search path string to an array > * of directory and JAR file URLs. > * > * @param path the search path string > * @return the resulting array of directory and JAR file URLs > */ > static URL[] pathToURLs(String path) { > StringTokenizer st = new StringTokenizer(path, File.pathSeparator); > URL[] urls = new URL[st.countTokens()]; > int count = 0; > while (st.hasMoreTokens()) { > URL url = fileToURL(new File(st.nextToken())); > if (url != null) { > urls[count++] = url; > } > } > if (urls.length != count) { > URL[] tmp = new URL[count]; > System.arraycopy(urls, 0, tmp, 0, count); > urls = tmp; > } > return urls; > } > > /** > * Returns the directory or JAR file URL corresponding to the specified > * local file name. > * > * @param file the File object > * @return the resulting directory or JAR file URL, or null if unknown > */ > static URL fileToURL(File file) { > String name; > try { > name = file.getCanonicalPath(); > } catch (IOException e) { > name = file.getAbsolutePath(); > } > name = name.replace(File.separatorChar, '/'); > if (!name.startsWith("/")) { > name = "/" + name; > } > // If the file does not exist, then assume that it's a directory > if (!file.isFile()) { > name = name + "/"; > } > try { > return new URL("file", "", name); > } catch (MalformedURLException e) { > throw new IllegalArgumentException("file"); > } > } src/share/classes/com/sun/tools/apt/main>sccs sccsdiff -r1.6 -r1.7 JavaCompiler.java ------- JavaCompiler.java ------- 401c401,402 < Map<String, String> origOptions) throws Throwable { --- > Map<String, String> origOptions, > ClassLoader aptCL) throws Throwable { 422c423 < apt.main(roots, origOptions); --- > apt.main(roots, origOptions, aptCL); src/share/classes/com/sun/tools/apt/comp>sccs sccsdiff -r1.12 -r1.13 Apt.java ------- Apt.java ------- 39,42d38 < import java.net.URLClassLoader; < import java.net.URL; < import java.io.File; < 45d40 < import java.net.MalformedURLException; 176c171,172 < Map<String, String> origOptions) { --- > Map<String, String> origOptions, > ClassLoader aptCL) { 231,258d226 < < /* < * Use a url class loader to look for classes on the < * user-specified class path. Prepend computed bootclass < * path, which includes extdirs, to the URLClassLoader apt < * uses. < */ < ClassLoader aptCL = null; < { < String aptclasspath = ""; < Paths paths = Paths.instance(context); < String bcp = ""; < Collection<String> bootclasspath = paths.bootClassPath(); < < if (bootclasspath != null) { < for(String s: bootclasspath) < bcp += (s + File.pathSeparator); < } < < // If the factory path is set, use that path < aptclasspath = options.get("-factorypath"); < if (aptclasspath == null) < aptclasspath = options.get("-classpath"); < < assert aptclasspath != null; < aptclasspath = (bcp + aptclasspath); < aptCL = new URLClassLoader(pathToURLs(aptclasspath)); < } 271c239,240 < java.util.List list = new LinkedList<AnnotationProcessorFactory>(); --- > java.util.List<AnnotationProcessorFactory> list = > new LinkedList<AnnotationProcessorFactory>(); 289c258 < java.util.Map<AnnotationProcessorFactory, Set<AnnotationTypeDeclaration>> factoryToAnnotation= --- > java.util.Map<AnnotationProcessorFactory, Set<AnnotationTypeDeclaration>> factoryToAnnotation = 481,535d449 < < // Borrowed from DocletInvoker < /** < * Utility method for converting a search path string to an array < * of directory and JAR file URLs. < * < * @param path the search path string < * @return the resulting array of directory and JAR file URLs < */ < static URL[] pathToURLs(String path) { < StringTokenizer st = new StringTokenizer(path, File.pathSeparator); < URL[] urls = new URL[st.countTokens()]; < int count = 0; < while (st.hasMoreTokens()) { < URL url = fileToURL(new File(st.nextToken())); < if (url != null) { < urls[count++] = url; < } < } < if (urls.length != count) { < URL[] tmp = new URL[count]; < System.arraycopy(urls, 0, tmp, 0, count); < urls = tmp; < } < return urls; < } < < /** < * Returns the directory or JAR file URL corresponding to the specified < * local file name. < * < * @param file the File object < * @return the resulting directory or JAR file URL, or null if unknown < */ < static URL fileToURL(File file) { < String name; < try { < name = file.getCanonicalPath(); < } catch (IOException e) { < name = file.getAbsolutePath(); < } < name = name.replace(File.separatorChar, '/'); < if (!name.startsWith("/")) { < name = "/" + name; < } < // If the file does not exist, then assume that it's a directory < if (!file.isFile()) { < name = name + "/"; < } < try { < return new URL("file", "", name); < } catch (MalformedURLException e) { < throw new IllegalArgumentException("file"); < } < } src/share/classes/com/sun/tools/apt/resources>sccs sccsdiff -r1.4 -r1.5 apt.properties ------- apt.properties ------- 52,53c52,53 < apt.opt.XPrintAptInvocations=< Print information about initial and recursive apt invocations --- > apt.opt.XPrintAptRounds=> Print information about initial and recursive apt rounds ###@###.### 2004-06-11
11-06-2004

EVALUATION Should be fixed. ###@###.### 2004-05-17
17-05-2004