JDK-8157773 : javac gives warnings on import of deprecated items
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 9
  • Priority: P3
  • Status: Closed
  • Resolution: Won't Fix
  • Submitted: 2016-05-24
  • Updated: 2025-02-25
  • Resolved: 2025-02-25
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Description
In the course of trying to deprecate the old javadoc API, I came across the following unsuppressible warnings for importing deprecated items.

Compiling 437 files for jdk.javadoc
/w/jjg/work/dev.8157606.deprecate.old.javadoc.api/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/internal/toolkit/util/Utils.java:39: warning: [deprecation] AnnotationDesc in com.sun.javadoc has been deprecated
import com.sun.javadoc.AnnotationDesc.ElementValuePair;
                      ^
/w/jjg/work/dev.8157606.deprecate.old.javadoc.api/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/DocletInvoker.java:48: warning: [deprecation] LanguageVersion in com.sun.javadoc has been deprecated
import static com.sun.javadoc.LanguageVersion.*;
                             ^
error: warnings found and -Werror specified
1 error
2 warnings


The items are notable for being nested items, not top-level items.

Also, since the references are in imports, they are not under the implicit suppression of being in a class which is itself being deprecated.
Comments
I believe the JLS forces this warning, and this was an intentional decision in JEP 211[1]. [1] https://openjdk.org/jeps/211
25-02-2025

By my reading, this behavior is correct according to the JLS. That is, if you import a nested class Foo.Bar, where class Foo is deprecated but class Bar is not, then you should get a warning due to the mention of Foo, even though you are really just importing Bar. JLS explanation (ยง9.6.4.6): "A deprecated program element is a module, class, interface, field, method, or constructor whose declaration is annotated with @ Deprecated." OK that means Foo is deprecated but not Bar. "A Java compiler must produce a deprecation warning when a ... deprecated program element is used (...referenced by name) in the declaration of a program element... unless ... The use is within an import declaration that imports the ... deprecated class" So the "unless" exception does not apply because the import declaration is importing class Bar, not class Foo. Additional examples are visible in the regression test for this here: https://github.com/openjdk/jdk/tree/master/test/langtools/tools/javac/warnings/NestedDeprecation
21-02-2025

Here's (I think) a simple reproduction test case: $ cat A.java package pkg1; @Deprecated public class A { public static class B { } } $ cat C.java package pkg2; import pkg1.A.B; @Deprecated @SuppressWarnings("deprecation") public class C { { System.out.println(new B()); } } $ javac -d ../../classes -Xlint:deprecation A.java C.java C.java:2: warning: [deprecation] A in pkg1 has been deprecated import pkg1.A.B; ^ 1 warning $ javac -version javac 19.0.1
07-02-2023

See work in JDK-8032211 and JDK-8042566.
25-05-2016