JDK-6634138 : Source generated in last round not compiled
  • Type: Bug
  • Component: core-libs
  • Sub-Component: javax.annotation.processing
  • Affected Version: 6
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2007-11-27
  • Updated: 2020-11-21
  • Resolved: 2011-03-08
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 Other
7 b85Fixed OpenJDK6Fixed
Related Reports
Relates :  
Description
It seems that javac does not compile source that is generated in the last round (when RoundEnvironment.processingOver() is true).

Although source generated in this round will not be annotation processed, it should still take part in javac's compile phase that happens after the "annotation processing".

Comments
SUGGESTED FIX # HG changeset patch # User darcy # Date 1266286857 28800 # Node ID af18e39569850733517428b83f3407934d673134 # Parent 7d9e3a15d2b32d5e7ac43d235fcb7df328b5affc 6634138: Source generated in last round not compiled Reviewed-by: jjg --- a/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Mon Feb 15 16:09:50 2010 -0800 +++ b/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Mon Feb 15 18:20:57 2010 -0800 @@ -874,20 +874,9 @@ public class JavacProcessingEnvironment JavaFileManager fileManager = currentContext.get(JavaFileManager.class); - List<JavaFileObject> fileObjects = List.nil(); - for (JavaFileObject jfo : filer.getGeneratedSourceFileObjects() ) { - fileObjects = fileObjects.prepend(jfo); - } - - compiler = JavaCompiler.instance(currentContext); - List<JCCompilationUnit> parsedFiles = compiler.parseFiles(fileObjects); - roots = cleanTrees(roots).reverse(); - - - for (JCCompilationUnit unit : parsedFiles) - roots = roots.prepend(unit); - roots = roots.reverse(); + List<JCCompilationUnit> parsedFiles = sourcesToParsedFiles(compiler); + roots = cleanTrees(roots).appendList(parsedFiles); // Check for errors after parsing if (compiler.parseErrors()) { @@ -921,11 +910,16 @@ public class JavacProcessingEnvironment break runAround; // No new files } } - runLastRound(xout, roundNumber, errorStatus, taskListener); + roots = runLastRound(xout, roundNumber, errorStatus, compiler, roots, taskListener); + // Set error status for any files compiled and generated in + // the last round + if (compiler.parseErrors()) + errorStatus = true; compiler.close(false); currentContext = contextForNextRound(currentContext, true); compiler = JavaCompiler.instance(currentContext); + filer.newRound(currentContext, true); filer.warnIfUnclosedFiles(); warnIfUnmatchedOptions(); @@ -979,10 +973,22 @@ public class JavacProcessingEnvironment return compiler; } + private List<JCCompilationUnit> sourcesToParsedFiles(JavaCompiler compiler) + throws IOException { + List<JavaFileObject> fileObjects = List.nil(); + for (JavaFileObject jfo : filer.getGeneratedSourceFileObjects() ) { + fileObjects = fileObjects.prepend(jfo); + } + + return compiler.parseFiles(fileObjects); + } + // Call the last round of annotation processing - private void runLastRound(PrintWriter xout, - int roundNumber, - boolean errorStatus, + private List<JCCompilationUnit> runLastRound(PrintWriter xout, + int roundNumber, + boolean errorStatus, + JavaCompiler compiler, + List<JCCompilationUnit> roots, TaskListener taskListener) throws IOException { roundNumber++; List<ClassSymbol> noTopLevelClasses = List.nil(); @@ -1003,6 +1009,15 @@ public class JavacProcessingEnvironment if (taskListener != null) taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND)); } + + // Add any sources generated during the last round to the set + // of files to be compiled. + if (moreToDo()) { + List<JCCompilationUnit> parsedFiles = sourcesToParsedFiles(compiler); + roots = cleanTrees(roots).appendList(parsedFiles); + } + + return roots; } private void updateProcessingState(Context currentContext, boolean lastRound) { --- a/test/tools/javac/T6403466.java Mon Feb 15 16:09:50 2010 -0800 +++ b/test/tools/javac/T6403466.java Mon Feb 15 18:20:57 2010 -0800 @@ -41,7 +41,6 @@ import com.sun.tools.javac.api.JavacTool @Wrap @SupportedAnnotationTypes("Wrap") -@SupportedSourceVersion(SourceVersion.RELEASE_6) public class T6403466 extends AbstractProcessor { static final String testSrcDir = System.getProperty("test.src"); @@ -73,23 +72,30 @@ public class T6403466 extends AbstractPr } public boolean process(Set<? extends TypeElement> annos, RoundEnvironment rEnv) { - Filer filer = processingEnv.getFiler(); - for (TypeElement anno: annos) { - Set<? extends Element> elts = rEnv.getElementsAnnotatedWith(anno); - System.err.println("anno: " + anno); - System.err.println("elts: " + elts); - for (TypeElement te: ElementFilter.typesIn(elts)) { - try { - Writer out = filer.createSourceFile(te.getSimpleName() + "Wrapper").openWriter(); - out.write("class " + te.getSimpleName() + "Wrapper { }"); - out.close(); - } catch (IOException ex) { - ex.printStackTrace(); + if (!rEnv.processingOver()) { + Filer filer = processingEnv.getFiler(); + for (TypeElement anno: annos) { + Set<? extends Element> elts = rEnv.getElementsAnnotatedWith(anno); + System.err.println("anno: " + anno); + System.err.println("elts: " + elts); + for (TypeElement te: ElementFilter.typesIn(elts)) { + try { + Writer out = filer.createSourceFile(te.getSimpleName() + "Wrapper").openWriter(); + out.write("class " + te.getSimpleName() + "Wrapper { }"); + out.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } } + } - } return true; + } + + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); } } --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/processing/6634138/Dummy.java Mon Feb 15 18:20:57 2010 -0800 @@ -0,0 +1,27 @@ +/* + * Copyright 2010 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. + */ + +/** + * A dummy class to be compiled. + */ +public class Dummy {} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/processing/6634138/ExerciseDependency.java Mon Feb 15 18:20:57 2010 -0800 @@ -0,0 +1,37 @@ +/* + * Copyright 2010 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. + */ + +/** + * Class to exercise dependencies on the two source files generated by + * T6634138.java, foo.WrittenAfterProcessing.java and + * foo.package-info.java. + */ +public class ExerciseDependency { + public static void main(String... args) { + foo.WrittenAfterProcessing wap = new foo.WrittenAfterProcessing(); + java.lang.Package pkg = wap.getClass().getPackage(); + Deprecated d = pkg.getAnnotation(Deprecated.class); + if (d == null) + throw new RuntimeException(); + } +} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/processing/6634138/T6634138.java Mon Feb 15 18:20:57 2010 -0800 @@ -0,0 +1,93 @@ +/* + * Copyright 2010 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 + * @bug 6634138 + * @author Joseph D. Darcy + * @summary Verify source files output after processing is over are compiled + * @compile T6634138.java + * @compile -processor T6634138 Dummy.java + * @run main ExerciseDependency + */ + +import java.lang.annotation.Annotation; +import java.io.*; +import java.util.Collections; +import java.util.Set; +import java.util.HashSet; +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; +import javax.annotation.processing.*; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.*; +import javax.lang.model.util.*; + +@SupportedAnnotationTypes("*") +public class T6634138 extends AbstractProcessor { + private Filer filer; + + public boolean process(Set<? extends TypeElement> annotations, + RoundEnvironment roundEnvironment) { + // Write out files *after* processing is over. + if (roundEnvironment.processingOver()) { + System.out.println("Writing out source files."); + try { + PrintWriter pw = new PrintWriter(filer.createSourceFile("foo.WrittenAfterProcessing").openWriter()); + try { + pw.println("package foo;"); + pw.println("public class WrittenAfterProcessing {"); + pw.println(" public WrittenAfterProcessing() {super();}"); + pw.println("}"); + } finally { + pw.close(); + } + + pw = new PrintWriter(filer.createSourceFile("foo.package-info").openWriter()); + try { + pw.println("@Deprecated"); + pw.println("package foo;"); + } finally { + pw.close(); + } + } catch(IOException io) { + throw new RuntimeException(io); + } + } + return true; + } + + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + + public void init(ProcessingEnvironment processingEnv) { + super.init(processingEnv); + filer = processingEnv.getFiler(); + } +} + + +
16-02-2010

PUBLIC COMMENTS See http://hg.openjdk.java.net/jdk7/tl/langtools/rev/af18e3956985
16-02-2010

EVALUATION Should be fixed.
27-11-2007