7026509: Cannot use JavaCompiler to create multiple CompilationTasks for partial compilations

Mon, 14 Mar 2011 11:48:41 -0700

author
jjg
date
Mon, 14 Mar 2011 11:48:41 -0700
changeset 930
cb119107aeea
parent 929
e2890b8369f7
child 931
c9432f06d9bc

7026509: Cannot use JavaCompiler to create multiple CompilationTasks for partial compilations
Reviewed-by: mcimadamore

src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/api/JavacTool.java file | annotate | diff | comparison | revisions
test/tools/javac/api/TestJavacTask_Lock.java file | annotate | diff | comparison | revisions
test/tools/javac/api/TestJavacTask_Multiple.java file | annotate | diff | comparison | revisions
test/tools/javac/api/TestJavacTask_ParseAttrGen.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java	Mon Mar 14 11:42:15 2011 -0700
     1.2 +++ b/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java	Mon Mar 14 11:48:41 2011 -0700
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -129,19 +129,11 @@
    1.11  
    1.12      public Boolean call() {
    1.13          if (!used.getAndSet(true)) {
    1.14 -            beginContext();
    1.15 +            initContext();
    1.16              notYetEntered = new HashMap<JavaFileObject, JCCompilationUnit>();
    1.17 -            try {
    1.18 -                compilerMain.setFatalErrors(true);
    1.19 -                result = compilerMain.compile(args, context, fileObjects, processors);
    1.20 -            } finally {
    1.21 -                endContext();
    1.22 -            }
    1.23 -            compilerMain = null;
    1.24 -            args = null;
    1.25 -            context = null;
    1.26 -            fileObjects = null;
    1.27 -            notYetEntered = null;
    1.28 +            compilerMain.setFatalErrors(true);
    1.29 +            result = compilerMain.compile(args, context, fileObjects, processors);
    1.30 +            cleanup();
    1.31              return result == 0;
    1.32          } else {
    1.33              throw new IllegalStateException("multiple calls to method 'call'");
    1.34 @@ -163,8 +155,11 @@
    1.35      }
    1.36  
    1.37      private void prepareCompiler() throws IOException {
    1.38 -        if (!used.getAndSet(true)) {
    1.39 -            beginContext();
    1.40 +        if (used.getAndSet(true)) {
    1.41 +            if (compiler == null)
    1.42 +                throw new IllegalStateException();
    1.43 +        } else {
    1.44 +            initContext();
    1.45              compilerMain.setOptions(Options.instance(context));
    1.46              compilerMain.filenames = new ListBuffer<File>();
    1.47              List<File> filenames = compilerMain.processArgs(CommandLine.parse(args));
    1.48 @@ -185,13 +180,12 @@
    1.49          }
    1.50      }
    1.51  
    1.52 -    private void beginContext() {
    1.53 +    private void initContext() {
    1.54          context.put(JavacTaskImpl.class, this);
    1.55          if (context.get(TaskListener.class) != null)
    1.56              context.put(TaskListener.class, (TaskListener)null);
    1.57          if (taskListener != null)
    1.58              context.put(TaskListener.class, wrap(taskListener));
    1.59 -        tool.beginContext(context);
    1.60          //initialize compiler's default locale
    1.61          JavacMessages.instance(context).setCurrentLocale(locale);
    1.62      }
    1.63 @@ -218,8 +212,15 @@
    1.64          };
    1.65      }
    1.66  
    1.67 -    private void endContext() {
    1.68 -        tool.endContext();
    1.69 +    void cleanup() {
    1.70 +        if (compiler != null)
    1.71 +            compiler.close();
    1.72 +        compiler = null;
    1.73 +        compilerMain = null;
    1.74 +        args = null;
    1.75 +        context = null;
    1.76 +        fileObjects = null;
    1.77 +        notYetEntered = null;
    1.78      }
    1.79  
    1.80      /**
    1.81 @@ -446,12 +447,12 @@
    1.82              }
    1.83              if (genList.isEmpty()) {
    1.84                  compiler.reportDeferredDiagnostics();
    1.85 -                compiler.log.flush();
    1.86 -                endContext();
    1.87 +                cleanup();
    1.88              }
    1.89          }
    1.90          finally {
    1.91 -            compiler.log.flush();
    1.92 +            if (compiler != null)
    1.93 +                compiler.log.flush();
    1.94          }
    1.95          return results;
    1.96      }
     2.1 --- a/src/share/classes/com/sun/tools/javac/api/JavacTool.java	Mon Mar 14 11:42:15 2011 -0700
     2.2 +++ b/src/share/classes/com/sun/tools/javac/api/JavacTool.java	Mon Mar 14 11:48:41 2011 -0700
     2.3 @@ -152,36 +152,6 @@
     2.4          return new JavacFileManager(context, true, charset);
     2.5      }
     2.6  
     2.7 -    private boolean compilationInProgress = false;
     2.8 -
     2.9 -    /**
    2.10 -     * Register that a compilation is about to start.
    2.11 -     */
    2.12 -    void beginContext(Context context) {
    2.13 -        if (compilationInProgress)
    2.14 -            throw new IllegalStateException("Compilation in progress");
    2.15 -        compilationInProgress = true;
    2.16 -        final JavaFileManager givenFileManager = context.get(JavaFileManager.class);
    2.17 -        context.put(JavaFileManager.class, (JavaFileManager)null);
    2.18 -        context.put(JavaFileManager.class, new Context.Factory<JavaFileManager>() {
    2.19 -            public JavaFileManager make(Context c) {
    2.20 -                if (givenFileManager != null) {
    2.21 -                    c.put(JavaFileManager.class, givenFileManager);
    2.22 -                    return givenFileManager;
    2.23 -                } else {
    2.24 -                    return new JavacFileManager(c, true, null);
    2.25 -                }
    2.26 -            }
    2.27 -        });
    2.28 -    }
    2.29 -
    2.30 -    /**
    2.31 -     * Register that a compilation is completed.
    2.32 -     */
    2.33 -    void endContext() {
    2.34 -        compilationInProgress = false;
    2.35 -    }
    2.36 -
    2.37      public JavacTask getTask(Writer out,
    2.38                               JavaFileManager fileManager,
    2.39                               DiagnosticListener<? super JavaFileObject> diagnosticListener,
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/test/tools/javac/api/TestJavacTask_Lock.java	Mon Mar 14 11:48:41 2011 -0700
     3.3 @@ -0,0 +1,111 @@
     3.4 +/*
     3.5 + * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
     3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.7 + *
     3.8 + * This code is free software; you can redistribute it and/or modify it
     3.9 + * under the terms of the GNU General Public License version 2 only, as
    3.10 + * published by the Free Software Foundation.
    3.11 + *
    3.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    3.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    3.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    3.15 + * version 2 for more details (a copy is included in the LICENSE file that
    3.16 + * accompanied this code).
    3.17 + *
    3.18 + * You should have received a copy of the GNU General Public License version
    3.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    3.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    3.21 + *
    3.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    3.23 + * or visit www.oracle.com if you need additional information or have any
    3.24 + * questions.
    3.25 + */
    3.26 +
    3.27 +/*
    3.28 + * @test
    3.29 + * @bug 7026509
    3.30 + * @summary Cannot use JavaCompiler to create multiple CompilationTasks for partial compilations
    3.31 + */
    3.32 +
    3.33 +import java.io.*;
    3.34 +import java.util.*;
    3.35 +import javax.tools.*;
    3.36 +import javax.tools.JavaCompiler.CompilationTask;
    3.37 +import com.sun.source.util.*;
    3.38 +
    3.39 +public class TestJavacTask_Lock {
    3.40 +    public static void main(String... args) throws Exception {
    3.41 +        new TestJavacTask_Lock().run();
    3.42 +    }
    3.43 +
    3.44 +    enum MethodKind {
    3.45 +        CALL {
    3.46 +            int test(CompilationTask t) {
    3.47 +                boolean ok = t.call();
    3.48 +                if (!ok)
    3.49 +                    throw new Error("compilation failed");
    3.50 +                return 1;
    3.51 +            }
    3.52 +        },
    3.53 +        PARSE {
    3.54 +            int test(CompilationTask t) {
    3.55 +                try {
    3.56 +                    ((JavacTask) t).parse();
    3.57 +                return 1;
    3.58 +                } catch (IOException ex) {
    3.59 +                    throw new Error(ex);
    3.60 +                }
    3.61 +            }
    3.62 +
    3.63 +        };
    3.64 +        abstract int test(CompilationTask t);
    3.65 +    }
    3.66 +
    3.67 +    JavaCompiler comp;
    3.68 +    StandardJavaFileManager fm;
    3.69 +
    3.70 +    void run() throws Exception {
    3.71 +        comp = ToolProvider.getSystemJavaCompiler();
    3.72 +        fm = comp.getStandardFileManager(null, null, null);
    3.73 +
    3.74 +        for (MethodKind first: MethodKind.values()) {
    3.75 +            for (MethodKind second: MethodKind.values()) {
    3.76 +                test(first, second);
    3.77 +            }
    3.78 +        }
    3.79 +
    3.80 +        if (errors > 0)
    3.81 +            throw new Exception(errors + " errors found");
    3.82 +    }
    3.83 +
    3.84 +    void test(MethodKind first, MethodKind second) {
    3.85 +        System.err.println("test: " + first + ", " + second);
    3.86 +        File testSrc = new File(System.getProperty("test.src"));
    3.87 +        String thisClassName = TestJavacTask_Lock.class.getName();
    3.88 +        Iterable<? extends JavaFileObject> files =
    3.89 +                fm.getJavaFileObjects(new File(testSrc, thisClassName + ".java"));
    3.90 +        File tmpDir = new File(first + "_" + second);
    3.91 +        tmpDir.mkdirs();
    3.92 +        List<String> options = Arrays.asList( "-d", tmpDir.getPath() );
    3.93 +        CompilationTask t = comp.getTask(null, fm, null, options, null, files);
    3.94 +
    3.95 +        try {
    3.96 +            first.test(t);
    3.97 +            second.test(t);
    3.98 +            error("No exception thrown");
    3.99 +        } catch (IllegalStateException e) {
   3.100 +            System.err.println("Expected exception caught: " + e);
   3.101 +        } catch (Exception e) {
   3.102 +            error("Unexpected exception caught: " + e);
   3.103 +            e.printStackTrace(System.err);
   3.104 +        }
   3.105 +
   3.106 +    }
   3.107 +
   3.108 +    void error(String msg) {
   3.109 +        System.err.println("Error: " + msg);
   3.110 +        errors++;
   3.111 +    }
   3.112 +
   3.113 +    int errors;
   3.114 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/test/tools/javac/api/TestJavacTask_Multiple.java	Mon Mar 14 11:48:41 2011 -0700
     4.3 @@ -0,0 +1,118 @@
     4.4 +/*
     4.5 + * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
     4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.7 + *
     4.8 + * This code is free software; you can redistribute it and/or modify it
     4.9 + * under the terms of the GNU General Public License version 2 only, as
    4.10 + * published by the Free Software Foundation.
    4.11 + *
    4.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    4.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    4.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    4.15 + * version 2 for more details (a copy is included in the LICENSE file that
    4.16 + * accompanied this code).
    4.17 + *
    4.18 + * You should have received a copy of the GNU General Public License version
    4.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    4.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    4.21 + *
    4.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    4.23 + * or visit www.oracle.com if you need additional information or have any
    4.24 + * questions.
    4.25 + */
    4.26 +
    4.27 +/*
    4.28 + * @test
    4.29 + * @bug 7026509
    4.30 + * @summary Cannot use JavaCompiler to create multiple CompilationTasks for partial compilations
    4.31 + */
    4.32 +
    4.33 +import java.io.*;
    4.34 +import java.util.*;
    4.35 +import javax.tools.*;
    4.36 +import javax.tools.JavaCompiler.CompilationTask;
    4.37 +import com.sun.source.util.*;
    4.38 +
    4.39 +public class TestJavacTask_Multiple {
    4.40 +    public static void main(String... args) throws Exception {
    4.41 +        new TestJavacTask_Multiple().run();
    4.42 +    }
    4.43 +
    4.44 +    final int MAX_TASKS = 3;
    4.45 +
    4.46 +    enum TestKind {
    4.47 +        CALL {
    4.48 +            int test(CompilationTask t) {
    4.49 +                boolean ok = t.call();
    4.50 +                if (!ok)
    4.51 +                    throw new Error("compilation failed");
    4.52 +                return 1;
    4.53 +            }
    4.54 +        },
    4.55 +        PARSE {
    4.56 +            int test(CompilationTask t) {
    4.57 +                try {
    4.58 +                    ((JavacTask) t).parse();
    4.59 +                return 1;
    4.60 +                } catch (IOException ex) {
    4.61 +                    throw new Error(ex);
    4.62 +                }
    4.63 +            }
    4.64 +
    4.65 +        };
    4.66 +        abstract int test(CompilationTask t);
    4.67 +    }
    4.68 +
    4.69 +    int count;
    4.70 +
    4.71 +    void run() throws Exception {
    4.72 +        JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
    4.73 +        StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
    4.74 +        for (TestKind tk: TestKind.values()) {
    4.75 +            test(comp, fm, tk);
    4.76 +        }
    4.77 +
    4.78 +        int expect = TestKind.values().length * MAX_TASKS;
    4.79 +        if (count != expect) {
    4.80 +            throw new Exception("Unexpected number of tests completed: " + count
    4.81 +                    + ", expected: " + expect);
    4.82 +        }
    4.83 +
    4.84 +    }
    4.85 +
    4.86 +    void test(JavaCompiler comp, StandardJavaFileManager fm, TestKind tk) {
    4.87 +        System.err.println("test " + tk);
    4.88 +        File testSrc = new File(System.getProperty("test.src"));
    4.89 +        String thisClassName = TestJavacTask_Multiple.class.getName();
    4.90 +        Iterable<? extends JavaFileObject> files =
    4.91 +                fm.getJavaFileObjects(new File(testSrc, thisClassName + ".java"));
    4.92 +
    4.93 +        List<CompilationTask> tasks = new ArrayList<CompilationTask>();
    4.94 +        for (int i = 1; i <= MAX_TASKS; i++) {
    4.95 +            File tmpDir = new File(tk + "_" + i);
    4.96 +            tmpDir.mkdirs();
    4.97 +            List<String> options = Arrays.asList( "-d", tmpDir.getPath() );
    4.98 +            CompilationTask t = comp.getTask(null, fm, null, options, null, files);
    4.99 +            ((JavacTask) t).setTaskListener(createTaskListener(tk, i));
   4.100 +            tasks.add(t);
   4.101 +        }
   4.102 +
   4.103 +        for (CompilationTask t: tasks)
   4.104 +            count += tk.test(t);
   4.105 +
   4.106 +        System.err.println();
   4.107 +    }
   4.108 +
   4.109 +    TaskListener createTaskListener(final TestKind tk, final int i) {
   4.110 +        return new TaskListener() {
   4.111 +
   4.112 +            public void started(TaskEvent e) {
   4.113 +                System.err.println(tk + "." + i + ": " + e + " started");
   4.114 +            }
   4.115 +
   4.116 +            public void finished(TaskEvent e) {
   4.117 +                System.err.println(tk + "." + i + ": " + e + " finished");
   4.118 +            }
   4.119 +        };
   4.120 +    }
   4.121 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/test/tools/javac/api/TestJavacTask_ParseAttrGen.java	Mon Mar 14 11:48:41 2011 -0700
     5.3 @@ -0,0 +1,127 @@
     5.4 +/*
     5.5 + * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
     5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.7 + *
     5.8 + * This code is free software; you can redistribute it and/or modify it
     5.9 + * under the terms of the GNU General Public License version 2 only, as
    5.10 + * published by the Free Software Foundation.
    5.11 + *
    5.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    5.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    5.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    5.15 + * version 2 for more details (a copy is included in the LICENSE file that
    5.16 + * accompanied this code).
    5.17 + *
    5.18 + * You should have received a copy of the GNU General Public License version
    5.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    5.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    5.21 + *
    5.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    5.23 + * or visit www.oracle.com if you need additional information or have any
    5.24 + * questions.
    5.25 + */
    5.26 +
    5.27 +/*
    5.28 + * @test
    5.29 + * @bug 7026509
    5.30 + * @summary Cannot use JavaCompiler to create multiple CompilationTasks for partial compilations
    5.31 + */
    5.32 +
    5.33 +import java.io.*;
    5.34 +import java.util.*;
    5.35 +import javax.lang.model.element.*;
    5.36 +import javax.tools.*;
    5.37 +import com.sun.source.tree.*;
    5.38 +import com.sun.source.util.*;
    5.39 +
    5.40 +public class TestJavacTask_ParseAttrGen {
    5.41 +    public static void main(String... args) throws Exception {
    5.42 +        new TestJavacTask_ParseAttrGen().run();
    5.43 +    }
    5.44 +
    5.45 +    JavaCompiler comp;
    5.46 +    StandardJavaFileManager fm;
    5.47 +
    5.48 +    void run() throws Exception {
    5.49 +        comp = ToolProvider.getSystemJavaCompiler();
    5.50 +        fm = comp.getStandardFileManager(null, null, null);
    5.51 +
    5.52 +        final boolean[] booleanValues = { false, true };
    5.53 +        for (boolean pk: booleanValues) {
    5.54 +            for (boolean ak: booleanValues) {
    5.55 +                for (boolean gk: booleanValues) {
    5.56 +                    test(pk, ak, gk);
    5.57 +                }
    5.58 +            }
    5.59 +        }
    5.60 +    }
    5.61 +
    5.62 +    void test(boolean pk, boolean ak, boolean gk) throws Exception {
    5.63 +        if (!pk && !ak && !gk)  // nothing to do
    5.64 +            return;
    5.65 +
    5.66 +        System.err.println("test: pk:" + pk + ", ak:" + ak + ", gk: " + gk);
    5.67 +        File testSrc = new File(System.getProperty("test.src"));
    5.68 +        String thisClassName = TestJavacTask_ParseAttrGen.class.getName();
    5.69 +        Iterable<? extends JavaFileObject> files =
    5.70 +                fm.getJavaFileObjects(new File(testSrc, thisClassName + ".java"));
    5.71 +        File tmpDir = new File((pk ? "p" : "") + (ak ? "a" : "") + (gk ? "g" : ""));
    5.72 +        tmpDir.mkdirs();
    5.73 +        fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(tmpDir));
    5.74 +        JavacTask t = (JavacTask) comp.getTask(null, fm, null, null, null, files);
    5.75 +        //t.setTaskListener(createTaskListener());
    5.76 +
    5.77 +        try {
    5.78 +            if (pk) {
    5.79 +                Iterable<? extends CompilationUnitTree> trees = t.parse();
    5.80 +                System.err.println(count(trees) + " trees parsed");
    5.81 +            }
    5.82 +
    5.83 +            if (ak) {
    5.84 +                Iterable<? extends Element> elems = t.analyze();
    5.85 +                System.err.println(count(elems) + " elements analyzed");
    5.86 +            }
    5.87 +
    5.88 +            if (gk) {
    5.89 +                Iterable<? extends JavaFileObject> classfiles = t.generate();
    5.90 +                System.err.println(count(classfiles) + " class files generated");
    5.91 +            }
    5.92 +        } catch (IOException e) {
    5.93 +            error("unexpected exception caught: " + e);
    5.94 +        }
    5.95 +
    5.96 +        File[] genFiles = tmpDir.listFiles();
    5.97 +        int expect = (gk ? 2 : 0); // main class and anon class for TaskListener
    5.98 +        if (genFiles.length != expect)
    5.99 +            error("unexpected number of files generated: " + genFiles.length
   5.100 +                    + ", expected: " + expect);
   5.101 +
   5.102 +        System.err.println();
   5.103 +    }
   5.104 +
   5.105 +    TaskListener createTaskListener() {
   5.106 +        return new TaskListener() {
   5.107 +            public void started(TaskEvent e) {
   5.108 +                System.err.println(e + " started");
   5.109 +            }
   5.110 +
   5.111 +            public void finished(TaskEvent e) {
   5.112 +                System.err.println(e + " finished");
   5.113 +            }
   5.114 +        };
   5.115 +    }
   5.116 +
   5.117 +    <T> int count(Iterable<T> items) {
   5.118 +        int count = 0;
   5.119 +        for (T item: items)
   5.120 +            count++;
   5.121 +        return count;
   5.122 +    }
   5.123 +
   5.124 +    void error(String msg) {
   5.125 +        System.err.println("Error: " + msg);
   5.126 +        errors++;
   5.127 +    }
   5.128 +
   5.129 +    int errors;
   5.130 +}

mercurial