<AWT Dev> [OpenJDK 2D-Dev] JDK 9 RFR of JDK-8066621: Suppress deprecation warnings in java.desktop module

joe darcy joe.darcy at oracle.com
Tue Dec 16 04:07:30 UTC 2014

On 12/15/2014 11:48 AM, Phil Race wrote:
> On 12/12/14 5:35 PM, joe darcy wrote:
>> Hi Phil,
>> On 12/12/2014 12:46 PM, Phil Race wrote:
>>> Hi,
>>> You did not provide a direct reference to the set of warnings that 
>>> were generated.
>>> fortunately I found it here :- 
>>> https://bugs.openjdk.java.net/browse/JDK-8066622
>> Each "Suppress deprecations warnings in foo" bug is linked to a "Fix 
>> deprecation warnings in foo" bug which lists the exact warnings.
> OK .. direct link would have helped.
>>> A couple of things I find 'unfortunate' are
>>> 1) In order to avoid a deprecation warning on one call/line of a 100 
>>> line method,
>>> the entire method is subject to the annotation. Eg :-
>>> dev/jdk/src/java.desktop/share/classes/javax/print/ServiceUI.java:226: 
>>> warning: [deprecation] show() in Dialog has been deprecated
>>> Other deprecated uses could silently creep into such a body of code.
>> That is true, but today deprecations warnings can (and do) creep into 
>> the entirely of the JDK without notice. Turning on the deprecation 
>> lint warning in the build will prevent that for the vast majority of 
>> code, which is why I want to get the remaining warning suppression 
>> bugs quickly pushed into JDK 9 so the build warning can be enabled. 
>> (This suppression effort was on hold until a small language change 
>> was recently implemented in JDK 9 to eliminate deprecation warnings 
>> just for importing a deprecated type.)
> Maybe a digression, but why go to the trouble, why would one 
> legitimately import a
> (deprecated) type and yet not use it ?

That is not the scenario that is problematic. If you 
@SuppressWarnings("deprecation") at the top of a class, that declaration 
annotation does *not* cover import statements. Additionally, a 
@SuppressWarnings("deprecation") annotation cannot be applied to import 
statements (this is a restriction since JDK 5).

Therefore, before the small language change to elide deprecation 
warnings on import statements made in JDK 9 (JEP 211), you could have a 
class where:

* A deprecated type was imported
* All the uses of the deprecated type in the code were @SuppressWarnings'ed

and still the class would generate deprecation warnings when it was 
compiled. To get a warning-free compile, the import statement would need 
to be removed and all the uses of the type replaced by fully qualified 
names, which is an unreasonable transformation to get warning-free code!

> But the gist of my point is that with this approach more warnings can 
> still creep in.
> Its unfortunate that the annotation system does not provide a way to 
> annotate the specific call
> and so it is not apparent to the reader what its suppressing.

Conversely, the downside of annotating every call site is that every 
call site is annotated...

All the @SuppressWarnings annotations are scoped to the declaration they 
are applied to (type, method/constructor, field). If you want to reduce 
the scope of warning suppression, a new scope can be introduced, such as 
a new method to contain the problematic construct. (This is analogous to 
introducing a new temporary variable with an @SuppressWarnings 
annotation to constrain the suppression to the expression used to 
initialize the variable, a technique that was used on occasion in the 
warnings cleanup changes earlier in JDK 9.)

>> For the "fix the warning" companion bug to this bug, I would 
>> recommend factoring out the deprecated method call into its own 
>> private method to limit the scope of the @SuppressWarning annotation. 
>> For this changeset, I didn't want to actually modify the contents or 
>> structure of any methods I so didn't undertake that kind of 
>> transformation.
> Adding a wrapper method seems artificial.
> Personally I would prefer to find a solution in the annotation system 
> or find a replacement or de-deprecating
> as Alan suggested might work in some cases, although Stuart Marks said 
> RMI has the same case.
>>> 2) Some significant fraction of all the warnings are for getPeer() :-
>>> dev/jdk/src/java.desktop/share/classes/java/awt/Container.java:821: 
>>> warning: [deprecation] getPeer() in Component has been deprecated
>> Yes, I also noticed that a sizeable percentage of the warnings were 
>> for uses of that one method.
>>> The issue here is that the deprecation javadoc tag is unable to 
>>> distinguish deprecated for
>>> external usage vs legitimate internal usage.
>> FYI, Stuart Mark / Dr. Deprecator gave an interesting talk at JavaOne 
>> this year covering the nuances of deprecation in the JDK:
>> https://oracleus.activeevents.com/2014/connect/sessionDetail.ww?SESSION_ID=6377
>>> There is no problem with code inside the desktop module
>>> calling getPeer() which is defined in this same module.  There may 
>>> not be many other APIs that
>>> have this similar issue, but if there are it might be better to find 
>>> some way to make it clear
>>> that we aren't suppressing warnings until we fix the code : rather 
>>> we really should not be
>>> receiving a warning here anyway since there is nothing to fix.
>> Well, the @SuppressWarnings annotation can be used to convey that 
>> information, perhaps supplemented by a comment or a wrapper method 
>> around getPeer; something like
>> /**
>>   * Package-access method somewhere in java.awt
>>   */
>> @SuppressWarnings("deprecation")
>> static java.awt Component privilegeOfPeerage(java.awt Component c)  {
>>     return c.getPeer();
>> }
> I don't think that conveys that its OK to use. It just adds work to 
> hide it in a different way.

A comment could be added to clarify "Package-level method to allow 
warning-free package-level use."

>>> Perhaps "Component. getPeer()"
>>> could acquire an annotation  like "module-nodeprecation" which 
>>> automatically suppresses the
>>> annotation processor  warnings for all such cases. If javac doesn't 
>>> know about modules perhaps
>>> we could utilise a javac flag that's used only by the JDK build to 
>>> indicate that an annotation
>>> like that should apply.
>> At this point, I think that level of solution would be overkill 
>> (especially given the JDK's historical lack of discipline around 
>> deprecation warnings).
> Well .. I think its worth more discussion than dismissing it out of hand.
>>> Regarding the show() case above I came across a puzzle.
>>> show() is first defined on Component, as is its 'replacement' 
>>> setVisible(boolean).
>>> It turns out that what we have in Component is
>>> public void setVisible(boolean b) {
>>>    show(b);
>>> }
>>> @Deprecated
>>> public void show(boolean b) {
>>>    if (b) {
>>>       show();
>>>   } else {
>>>       hide();
>>> }
>>> @Deprecated
>>> public void show() {
>>>  ...
>>> }
>>> So I am puzzled why those uses within Component aren't suppressed in 
>>> your webrev ?
>>> Is there some automatic suppression of the warnings within the class 
>>> that does
>>> the deprecation ? 
>> Yes, quoting from the JLS:
>> "A Java compiler must produce a deprecation warning when a type, 
>> method, field, or constructor whose declaration is annotated with 
>> |@Deprecated| is used (overridden, invoked, or referenced by name) in 
>> a construct which is explicitly or implicitly declared, unless:
>>     * [...]
>>     * The use and declaration are both within the same outermost class. "
>> http://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-
> OK. So that's not as well known as you'd think. It stumped Stuart.
> I had to 'infer'  this from the observed behaviour.

Although it may be surprising, that aspect of deprecation goes back a 
long ways.

> At this point I'll approve the changes although I would like full 
> consideration
> of enhancements to the APS in the future.
> Also I believe this should go to client. If it gets pushed by the end 
> of the day
> or at least no later than the end of tomorrow it should be integrated 
> by 23rd.

I've pushed the changes to the client repo.

I will be soon preparing two additional changesets for review to perform 
similar deprecation warning suppression in platform-specific client code.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/awt-dev/attachments/20141215/432385c1/attachment.html>

More information about the awt-dev mailing list