Invoking code generated by an annotation processor

Jonathan Gibbons jonathan.gibbons at oracle.com
Thu Mar 3 16:25:07 UTC 2016


JDK-8151194
https://bugs.openjdk.java.net/browse/JDK-8151194

-- Jon

On 03/03/2016 07:48 AM, Stéphane NICOLAS wrote:
> Thx a lot Jon, it's perfect like this. We wil soon pass to java 9 in 
> our android development anyway.
> If you could link the issue here once you create it, so that we can 
> follow it up, that would be great.
>
> S.
>
> 2016-03-03 7:37 GMT-08:00 Jonathan Gibbons 
> <jonathan.gibbons at oracle.com <mailto:jonathan.gibbons at oracle.com>>:
>
>     Stephane,
>
>     I will create an issue to track this.  I cannot make promises
>     about fixing this, but if we do, it would be fixed in 9 first, and
>     then maybe backported to 8.
>
>     -- Jon
>
>
>
>     On 03/02/2016 06:48 PM, Stéphane NICOLAS wrote:
>>     @jonathan, is there any chance this will get fixed in a future
>>     release of javac ? (7 &/or 8+, we actually don't really mind
>>     about java 7 on our side).
>>
>>     Thx in advance,
>>      Stephane
>>
>>     2016-02-19 19:50 GMT-08:00 Stéphane NICOLAS
>>     <steff.nicolas at gmail.com <mailto:steff.nicolas at gmail.com>>:
>>
>>         Thx Joe for this historical precision, I appreciate it.
>>
>>         I read carefully, and when the specs says :
>>>         If the source code is not syntactically well-formed or has
>>>         some other irrecoverable error that could not be removed by
>>>         the generation of new types, a model may or may not be
>>>         provided as a quality of implementation issue.
>>         In the 2 cases we highlighted : a static import error or an
>>         erroneous annotation value, it's hard to say here if a source
>>         with those errors is syntactically valid.
>>
>>         _If we consider it syntactically valid : _then those errors
>>         are not recoverable, as they prevent the annotation processor
>>         from running. So those errors should be reported. And javac
>>         does that. But it also reports all cals to generated code as
>>         errors, which is our concern.
>>
>>         Later, the specs says :
>>>         If a program is syntactically valid but erroneous in some
>>>         other fashion, any returned model must have no less
>>>         information than if all the method bodies in the program
>>>         were replaced by "throw new RuntimeException();"
>>         Here, javac seems to fail in our case as the source code is
>>         syntactically valid, but erroneous in some other fashion, but
>>         our generated code is not assumed to have the form of empty
>>         classes, methods etc.. The annotation processor is simply not
>>         run and those errors are reported.
>>
>>         So, if such errors are not considered syntax errors, javac
>>         doesn't follow the specs.
>>
>>         _If we consider the program is not syntactically valid :
>>         _then we fall in a loophole of fuzzyness of the specs : a
>>         model may or may not be provided as a quality of
>>         implementation issue. It looks like it's not possible to
>>         generate a model that could be passed to annotation
>>         processors because of those errors. Then only those should be
>>         reported.
>>
>>         I tend to think there is something missing on this matter in
>>         the specs you mention : an intermediary class of error.
>>
>>         Unrecoverable errors :
>>
>>           * syntax errors are about the form of the program (missing
>>             commas, braces, etc. name it). Those are reported well by
>>             javac, and only them are reported. Perfect
>>           * model building errors : static imports and annotation
>>             values errors. Those are also reported well by javac but
>>             they drag along with them error to generated code, the
>>             recoverable errors below.
>>
>>         Recoverable errors :
>>
>>           * unknown classes or members of known classes : those are
>>             not considered as error before annotation processing
>>             takes place. Which is OK, but they are reported in case
>>             of model building errors, which is our concern.
>>
>>         So we can say here, to summarize the problem differently that
>>         right after parsing a source and considering it valid, javac
>>         open a list of errors it finds in the source. It adds all
>>         recoverable errors it finds to save them for a next phase of
>>         processing after annotation processing. But at that very
>>         precise moment, it also adds to the error list the non
>>         recoverable model building errors. And if one is found, then
>>         all errors are reported, which is not correct.
>>
>>         The solution would be to separate model building errors and
>>         recoverable errors right after having considered a program
>>         syntactically valid.
>>         Maybe there is an intermediary phase needed to identify
>>         strictly non recoverable model building errors and list them,
>>         before building the model and detecting recoverable errors,
>>         which javac handles well.
>>
>>         S.
>>
>>
>>         2016-02-19 16:15 GMT-08:00 Joseph D. Darcy
>>         <joe.darcy at oracle.com <mailto:joe.darcy at oracle.com>>:
>>
>>             Hello,
>>
>>             On 2/17/2016 11:00 AM, Jonathan Gibbons wrote:
>>>             Stéphane,
>>>
>>>             Internally, during the period before anno processing,
>>>             javac categorizes errors as recoverable or not, where
>>>             "recoverable" means "could this error conceivably be
>>>             fixed by running annotation processors, which may
>>>             generate code."
>>>
>>>             It may be that we have to examine the scenario you
>>>             describe to decide if the error should be marked as
>>>             recoverable.
>>>
>>
>>             To provide some additional historical context here, the
>>             first generation annotation processing of apt in JDK 5 as
>>             well as the standardized successor of javax.lang.model
>>             and javax.annotation.processing in JDK 6 and later shared
>>             a requirement of having to be able to process incomplete
>>             programs. In particular, to allow processors to generated
>>             missing subclasses and even superclasses of the the
>>             initial set of sources.
>>
>>             In general, it is impractical to describe exactly how a
>>             compiler should model an incorrect program. The JSR 269
>>             expert group took some some pains to craft a
>>             specification would balance the need for predictability
>>             while also allowing some room for implementation-specific
>>             behavior: current version of this specification with some
>>             refinements [1] over the years:
>>
>>>             During annotation processing, operating on incomplete or
>>>             erroneous programs is necessary; however, there are
>>>             fewer guarantees about the nature of the resulting
>>>             model. If the source code is not syntactically
>>>             well-formed or has some other irrecoverable error that
>>>             could not be removed by the generation of new types, a
>>>             model may or may not be provided as a quality of
>>>             implementation issue. If a program is syntactically
>>>             valid but erroneous in some other fashion, any returned
>>>             model must have no less information than if all the
>>>             method bodies in the program were replaced by "throw new
>>>             RuntimeException();". If a program refers to a missing
>>>             type XYZ, the returned model must contain no less
>>>             information than if the declaration of type XYZ were
>>>             assumed to be "class XYZ {}", "interface XYZ {}", "enum
>>>             XYZ {}", or "@interface XYZ {}". If a program refers to
>>>             a missing type XYZ<K1, ... ,Kn>, the returned model must
>>>             contain no less information than if the declaration of
>>>             XYZ were assumed to be "class XYZ<T1, ... ,Tn> {}" or
>>>             "interface XYZ<T1, ... ,Tn> {}"
>>             http://docs.oracle.com/javase/8/docs/api/javax/lang/model/element/package-summary.html
>>
>>             As Jon alluded to earlier in this thread, how javac
>>             implements this aspect of the spec has evolved over time
>>             with the current intention to forge ahead when generating
>>             a missing type could allow the whole set of sources to
>>             compile successfully.
>>
>>             Cheers,
>>
>>             -Joe
>>
>>             [1] https://bugs.openjdk.java.net/browse/JDK-7003550
>>
>>
>>
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20160303/670ad95d/attachment-0001.html>


More information about the compiler-dev mailing list