RFR: JDK-8187950: javax.lang.model APIs throws CompletionFailure or a subtype of CompletionFailure.
Jan Lahoda
jan.lahoda at oracle.com
Wed Feb 14 15:33:59 UTC 2018
On 14.2.2018 07:52, Liam Miller-Cushon wrote:
> I did some more testing and am seeing regressions with a few existing
> annotation processors. In some cases the processors relied on a
> completion failure being thrown, and adding explicit checks for error
> types fixes them.
>
> There was another example I'm less sure about, where a compilation that
> previously failed with a 'class file not found' error now succeeds but
> the processor sees incorrect information. In the example below the class
> file for the interface B is missing, and its element kind is reported as
> CLASS.
One thing I'd like to point out is that this can (AFAIK) happen even now
- if the interface B is completed in a way that will throw away the
CompletionFailure (e.g. Elements.getTypeElement), then the subsequent
code will AFAIK see the same state as this AP sees. So it seemed
somewhat acceptable to let the behavior be similar in case where the
CompletionFailure would be thrown, esp. since I didn't see a good way to
do better.
Today, I got an idea that might solve this issue without too much
hassle, sketched here:
http://cr.openjdk.java.net/~jlahoda/8187950/webrev.01-ext/
Will need more testing, but possibly could work. Any opinions/ideas?
Thanks for the feedback,
Jan
>
> === L.java
> class A {}
> interface B {}
> class L extends A implements B {}
> === T.java
> class T {}
> === P.java
> import java.util.Set;
> import javax.annotation.processing.*;
> import javax.lang.model.*;
> import javax.lang.model.element.*;
> import javax.lang.model.type.*;
>
> @SupportedAnnotationTypes("*")
> public class P extends AbstractProcessor {
>
> @Override
> public SourceVersion getSupportedSourceVersion() {
> return SourceVersion.latest();
> }
>
> @Override
> public boolean process(Set<? extends TypeElement> annotations,
> RoundEnvironment roundEnv) {
> for (TypeMirror st :
> processingEnv
> .getTypeUtils()
>
> .directSupertypes(processingEnv.getElementUtils().getTypeElement("L").asType()))
> {
> System.err.println(st.getKind() + ": " + st);
> Element te = ((DeclaredType) st).asElement();
> System.err.println(" " + te.getKind() + ": " + te);
> }
> return false;
> }
> }
> ===
>
> $ javac *.java && rm B.class
> # with JDK 10+43
> $ javac -fullversion -implicit:none -sourcepath : -processor P T.java
> javac full version "10+43"
> DECLARED: A
> CLASS: A
> DECLARED: B
> error: cannot access B
> class file for B not found
> Consult the following stack trace for details.
> com.sun.tools.javac.code.Symbol$CompletionFailure: class file for B
> not found
> ...
> $ echo $?
> 1
>
> # with http://cr.openjdk.java.net/~jlahoda/8187950/webrev.01/
> <http://cr.openjdk.java.net/~jlahoda/8187950/webrev.01/>
> $ javac -implicit:none -sourcepath : -processor P T.java
> DECLARED: A
> CLASS: A
> DECLARED: B
> CLASS: B
> ...
> $ echo $?
> 0
>
> On Tue, Feb 13, 2018 at 4:26 AM, Jan Lahoda <jan.lahoda at oracle.com
> <mailto:jan.lahoda at oracle.com>> wrote:
>
> On 12.2.2018 19:50, Liam Miller-Cushon wrote:
>
> Hi Jan,
>
> I've run into the same problem a few times, and made some half-baked
> experiments around not caching completion failures [1]. The
> approach you
> describe sounds good to me. Also,
>
>
> Thanks.
>
> * this will fix JDK-8177436 [2] too
>
>
> I double-checked, and it indeed fixes that.
>
> * there's a minor typo in the javadoc
> for DeferredCompletionFailureHandler - "throw the the client code"
>
>
> Fixed in the updated webrev.
>
> Thanks for the feedback,
> Jan
>
>
> [1]
> http://mail.openjdk.java.net/pipermail/compiler-dev/2017-March/010883.html
> <http://mail.openjdk.java.net/pipermail/compiler-dev/2017-March/010883.html>
> <http://mail.openjdk.java.net/pipermail/compiler-dev/2017-March/010883.html
> <http://mail.openjdk.java.net/pipermail/compiler-dev/2017-March/010883.html>>
> [2] https://bugs.openjdk.java.net/browse/JDK-8177436
> <https://bugs.openjdk.java.net/browse/JDK-8177436>
> <https://bugs.openjdk.java.net/browse/JDK-8177436
> <https://bugs.openjdk.java.net/browse/JDK-8177436>>
>
> On Mon, Feb 12, 2018 at 4:43 AM, Jan Lahoda
> <jan.lahoda at oracle.com <mailto:jan.lahoda at oracle.com>
> <mailto:jan.lahoda at oracle.com <mailto:jan.lahoda at oracle.com>>>
> wrote:
>
> Hi,
>
> Currently, when a calling some API methods, the client (e.g.
> TaskListener, an annotation Processor or a JavacTask
> client) may get
> a CompletionFailure, if the given Symbol was not completed
> yet. This
> is not only problematic for the clients, but if the client
> catches
> and ignores the exception, the javac may be unable to report an
> appropriate error.
>
> The proposed patch here:
> -separates "user " and "javac" modes, in which
> CompletionFailure
> handling differs a bit
> -in javac mode, CompletionFailures should be handled as
> they are
> currently
> -in user (code) mode, when a CompletionFailure is thrown
> (and would
> go outside of an API method), the API method will suppress the
> exception, and the Symbol's state (completer, kind, type)
> will be
> restored to original when the mode is switched back to
> javac mode.
> If the Symbol is then completed again inside javac, the
> CompletionFailure is thrown again and the appropriate
> errors are
> reported.
>
> Bug: https://bugs.openjdk.java.net/browse/JDK-8187950
> <https://bugs.openjdk.java.net/browse/JDK-8187950>
> <https://bugs.openjdk.java.net/browse/JDK-8187950
> <https://bugs.openjdk.java.net/browse/JDK-8187950>>
> Webrev:
> http://cr.openjdk.java.net/~jlahoda/8187950/webrev.00/
> <http://cr.openjdk.java.net/~jlahoda/8187950/webrev.00/>
> <http://cr.openjdk.java.net/~jlahoda/8187950/webrev.00/
> <http://cr.openjdk.java.net/~jlahoda/8187950/webrev.00/>>
>
> How does this look?
>
> Thanks,
> Jan
>
>
>
More information about the compiler-dev
mailing list