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