JavacTask.generate bug?

Joshua Maurice joshuamaurice at gmail.com
Thu May 27 15:48:35 PDT 2010


Silly question: is there a known bug in JavacTask.generate? I did a quick
google search of the bug archives, and it did not come up. It seems that
depending on the order of JavaFileObjects used to create the JavacTask, the
fifth argument to javax.tools.JavaCompiler.getTask, it skips or does not
skip generating files. Here's my stand alone example:


import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import javax.lang.model.element.Element;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.util.JavacTask;

public class Foo {
    public static void main(String[] args) throws IOException {
        final File srcRoot = new File("C:/foo/src");
        final File tgtRoot = new File("C:/foo/tgt");
        writeToFile(new File(srcRoot + "/T3.java"), "public class T3 {
public static final int C = 1; }\n");
        writeToFile(new File(srcRoot + "/T2.java"), "public class T2 extends
T3 {}\n");
        writeToFile(new File(srcRoot + "/T1.java"), "public class T1 extends
T2 {}\n");
        writeToFile(new File(srcRoot + "/Test.java"), "public class Test {
public static final int D = T1.C; }\n");

        final List<File> sourceFiles = Arrays.asList(new File[]{
                new File(srcRoot, "/T2.java"),
                new File(srcRoot, "/T1.java"),
                new File(srcRoot, "/T3.java"),
                new File(srcRoot, "/Test.java"),
                });

        final StringWriter compilerOutputStream = new StringWriter();

        final List<String> compileOptions = Arrays.asList(new String[]{"-g",
"-source", "1.6", "-Xlint:unchecked", "-d", tgtRoot.toString()});
        final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        DiagnosticCollector<JavaFileObject> diagnosticCollector = new
DiagnosticCollector<JavaFileObject>();
        final StandardJavaFileManager fileManager =
compiler.getStandardFileManager(diagnosticCollector, null, null);
        final Iterable<? extends JavaFileObject> sourceFileObjects =
fileManager.getJavaFileObjectsFromFiles(sourceFiles);
        System.out.println("1- javac given java source JavaFileObjects " +
sourceFileObjects);
        final JavaCompiler.CompilationTask task =
compiler.getTask(compilerOutputStream, fileManager, null, compileOptions,
null, sourceFileObjects);
        JavacTask javacTask = (JavacTask)task;

        if (false) { //TOGGLE THIS

            final Iterable<? extends CompilationUnitTree> parsedTrees =
javacTask.parse();
            final Iterable<? extends Element> analyzedTrees =
javacTask.analyze();
            final Iterable<? extends JavaFileObject> generatedFiles =
javacTask.generate();

            System.out.println("2- " + size(parsedTrees) + " " +
size(analyzedTrees) + " " + size(generatedFiles));

            System.out.print("3-");
            for (JavaFileObject f : generatedFiles)
                System.out.print(" " + f);
            System.out.println("");
        } else {
            final boolean javacCallReturn = javacTask.call();
            System.out.println("4- " + javacCallReturn);
        }

        System.out.print("5-");
        for (File f : tgtRoot.listFiles())
            System.out.print(" " + f);
        System.out.println("");

        System.out.println("----");
        System.out.println(compilerOutputStream.toString());
    }

    private static <E> int size(Iterable<E> x) {
        int n = 0;
        for (Iterator<E> iter = x.iterator(); iter.hasNext(); ++n)
            iter.next();
        return n;
    }

    private static void writeToFile(File f, String str) throws IOException
{
        f.getParentFile().mkdirs();
        BufferedWriter fout = new BufferedWriter(new FileWriter(f));
        try {
            fout.write(str);
            fout.flush();
        } finally {
            fout.close();
        }
    }
}


When TOGGLE THIS is true, it calls "generate" on the JavacTask. The output
on some execution on my computer is:
    1- javac given java source JavaFileObjects [C:\foo\src\T2.java,
C:\foo\src\T1.java, C:\foo\src\T3.java, C:\foo\src\Test.java]
    2- 4 4 2
    3- C:\foo\tgt\T3.class C:\foo\tgt\Test.class
    5- C:\foo\tgt\T1.class C:\foo\tgt\T2.class C:\foo\tgt\T3.class
C:\foo\tgt\Test.class
    ----

When TOGGLE THIS is false, it calls "call" on the JavacTask. The output on
some execution on my computer is:
    1- javac given java source JavaFileObjects [C:\foo\src\T2.java,
C:\foo\src\T1.java, C:\foo\src\T3.java, C:\foo\src\Test.java]
    4- true
    5- C:\foo\tgt\T1.class C:\foo\tgt\T2.class C:\foo\tgt\T3.class
C:\foo\tgt\Test.class
    ----

When the order of file objects given to the JavacTask is altered, it starts
to work. Ex:
        final List<File> sourceFiles = Arrays.asList(new File[]{
                new File(srcRoot, "/Test.java"),
                new File(srcRoot, "/T3.java"),
                new File(srcRoot, "/T2.java"),
                new File(srcRoot, "/T1.java"),
                });
gives output:
    1- javac given java source JavaFileObjects [C:\foo\src\Test.java,
C:\foo\src\T3.java, C:\foo\src\T2.java, C:\foo\src\T1.java]
    2- 4 4 4
    3- C:\foo\tgt\Test.class C:\foo\tgt\T3.class C:\foo\tgt\T2.class
C:\foo\tgt\T1.class
    5- C:\foo\tgt\T1.class C:\foo\tgt\T2.class C:\foo\tgt\T3.class
C:\foo\tgt\Test.class
    ----

So, it appears as though I can work around this bug. I just have to create
two different JavacTasks for each "javac task" aka "pom.xml", one to do the
actual class file generation, done with the member function "call", and a
second JavacTask invocation to get the analyzed parse trees to get the used
types during compile (which I'm still working on figuring out how to do).

Finally:
    C:\Documents and Settings\jmaurice>javac -version
    javac 1.6.0_20
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20100527/be278d56/attachment.html 


More information about the compiler-dev mailing list