Deprecation beyond the level of types
alex.buckley at oracle.com
Tue Apr 3 00:49:46 UTC 2018
On 4/1/2018 4:31 AM, Stephan Herrmann wrote:
> Packages: JLS & javadoc agree that @Deprecated applied to a package
> has no effect. Given that @Target explicitly includes PACKAGE this
> looks inconsistent to me. A user adding @Deprecated to a package would
> certainly expect *some* effect, no?
I understand that JSR 175 forgot to restrict the targets of the
Deprecated annotation type, which meant it was possible to write
@Deprecated on a package declaration. This should have been disallowed,
because (as you imply) no-one conceived of a warning or an error when
the package is imported/used. The targets of Deprecated were specified
in Java SE 7 as part of the background work for JSR 308; PACKAGE was
included for source compatibility with package declarations that already
> JLS argues about the same programmer developing the package and
> managing its export from then enclosing module. I fail to see how this
> justifies the decision to let deprecation of packages go without warning.
> If a library developer deprecates an exported package, shouldn't this
> signal to consumers of the library, that they should migrate away from
> using types within that package? Currently it doesn't, because consumers
> will see no effect of that deprecation.
The JLS "argument" that you mention is a corner case that concerns a
deprecated package being exported in a qualified fashion. It's not meant
to be a general justification "to let deprecation of packages go without
warning". The reason why exporting a deprecated package doesn't generate
a warning is because no other use of a deprecated package generates a
warning. (And note JEP 211, which reduced the population of warnings for
a deprecated package even further, at `import`.)
Of course, we could change this behavior, and have long discussions
about whether deprecating a package means "deprecate the package, not
its types" or "deprecate its types, not the package". But it's not on
the radar at this time.
> Modules: I could find no reference in JLS specifying any relation between
> modules and deprecation.
I enumerated "program elements" in the first sentence of JLS 126.96.36.199
specifically to show that "modules" are as subject to deprecation as
classes, fields, etc. It's easily concluded from the section that, say,
requiring a deprecated module (directly or indirectly) should cause a
> In the javadoc of @Deprecated, however, I find
> some additions (apparently not provided/reviewed via jigsaw), notably:
> "A module being deprecated does not cause warnings to be issued for
> uses of types within the module."
> For a named module, this makes sense, since "requires" will already raise
> a warning for the deprecated module, and hence flagging each use of a type
> from that module adds little value.
> For unnamed modules, however, this seems to completely bypass any module-
> level deprecation. There is no "requires" that could be flagged, and use
> of types from the deprecated modules isn't flagged either.
> Ergo: most today's consumers of libraries that deprecate either a module
> or a package will not be informed about this deprecation by compilers.
> I see two consequences from the above:
> There's little to no incentive to use @Deprecated at any level greater than
> types, because it is not reliably communicated to users. We keep thinking
> in terms of types, not modules (not even packages).
> Second, developers of unnamed modules will see fewer deprecation warnings.
> Hence, migrating from unnamed to named has an additional burden of having
> to deal with warnings that could have been dealt with before, but simply
> weren't visible.
You're right -- the JLS does not mandate a warning when compiling code
on the classpath that uses code in deprecated modules. But it's
short-sighted to say that deprecation warnings mandated by
modularization are a burden; they communicate important information
which couldn't be communicated by the compiler before.
More information about the jigsaw-dev