Deprecating java.util.Date, java.util.Calendar and java.text.DateFormat and their subclasses
Victor Williams Stafusa da Silva
victorwssilva at gmail.com
Tue May 10 20:03:58 UTC 2022
Well, getting up from what Stuart Marks and others said, there are some
classes that are obsolescent, but can't be deprecated because this would
force user to add @SuppressWarnings("deprecation") in a bunch of places or
just ignore warnings.
As Ron Pressler said, some other annotation could do the job. But how?
Part of the problem is that @SuppressWarnings("deprecation") isn't
selective about which deprecated things are allowed and which aren't. Other
problem is that @Deprecated is taken very seriously and harshly. Every
single usage of the deprecated class/method/whatever will be flagged in a
different warning.
First, we could add @Discouraged for classes and interfaces that are
discouraged, but the compiler should not warn about them too harshly as it
does about @Deprecated.
Then, a class, method, constructor, package or module could then be
annotated with @ExportsDiscouraged({Date.class, Calendar.class}) and
@UsesDiscouraged({StringBuffer.class, Vector.class}) to tell the compiler
that the usage of the discouraged classes in the annotated class, method,
constructor, package or module is ok.
If the compiler sees any usage of the discouraged element which was not
declared in the @ExportsDiscouraged or @UsesDiscouraged annotation or any
discouraged element declared in the public API that is not declared in the
@ExportsDiscouraged, it prints a message only once. Not much different than
the actual "Note: Some messages have been simplified; recompile with
-Xdiags:verbose to get full output" message. Something like "Note: Some
discouraged elements were used; recompile with -Xlint:discouraged to get
full output". If it is recompiled with the "-Xlint:discouraged", it will
show which discouraged classes or interfaces not allowed with
@ExportsDiscouraged or @UsesDiscouraged were used.
Since @ExportsDiscouraged or @UsesDiscouraged are annotations that take an
array of class literals, there would be no mechanism for discouraging
fields, methods, constructors, packages or modules. Only classes and
interfaces could be discouraged.
Further, @Discouraged would be silently ignored if the annotated element
also features @Deprecated. Non-discouraged classes/interfaces used in the
values of @ExportsDiscouraged or @UsesDiscouraged would be silently ignored.
Finally, adding array classes or primitives to @ExportsDiscouraged or
@UsesDiscouraged would be a compiler error, so nobody would do
@ExportsDiscouraged({int.class, void.class, String[].class})
Em ter., 10 de mai. de 2022 às 16:01, Stuart Marks <stuart.marks at oracle.com>
escreveu:
> You're definitely on to something in that java.util.Date is obsolete, or
> obsolescent, and perhaps conceptually at least it should be deprecated. If
> I were
> reviewing some code that used Date I'd certainly flag the issue. The main
> difficulty
> is that its usage is entrenched in implementation code, but more
> importantly, in APIs.
>
> In another message you listed several dozen places in the JDK that use
> Date and
> related APIs. It would be certain amount of work to introduce replacements
> that use
> newer APIs and to suppress the warnings resulting from the existing APIs.
> This is a
> bunch of work, but it's not intractable. However, the benefits aren't very
> high, and
> so the priority is low.
>
> That's just the JDK. What also needs to be considered is the amount of
> code out
> there that *uses* these APIs. Most of the usages are in legacy code, which
> people
> are unlikely to want to spend a large effort on migrating. In addition,
> Date and
> friends are used in third party library *APIs*, which have their own
> users. There's
> a lot of this code.
>
> There are a few possible responses maintainers of this code can take when
> new
> deprecations appear.
>
> - Ignoring them. OK, if people ignore deprecation, then it doesn't
> really matter
> what we do.
>
> - Disable deprecation warnings. If people had warnings enabled, they
> presumably
> found value in having those warnings. Mostly this is useful for preventing
> new code
> from using deprecated APIs. If a lot of many not-very-useful warnings
> suddenly
> appear, people might disable warnings entirely, and thus miss the warnings
> they'd
> actually find useful. This defeats the purpose of having the warnings.
>
> - Migrate code to use other APIs. Some people will do this, if they're
> in a
> position to do so. Maintainers of legacy code generally are not able to do
> this.
> Library maintainers are also often not in a position to do this, as they
> have their
> own compatibility concerns.
>
> - Suppress warnings at the call sites using @SuppressWarnings. This is
> probably
> the most common alternative to code migration. This isn't a terrible
> option, but
> it's tedious, low-value work, and people don't like being forced to do
> work that
> isn't providing value to them.
>
> This last point may be more significant than you think. When I deprecated
> java.util.Observer/Observable in Java 9, there was very little usage of
> these
> classes; yet I received a bunch of complaints from people having to deal
> with the
> warnings. Date and related classes have several orders of magnitude more
> usage. The
> number of warnings generated will be huge, and the effort required to deal
> with them
> will be tremendous.
>
> By the way, all this also applies to other obsolescent but widely used
> classes such
> as Vector, Hashtable, LinkedList, URL, etc.
>
> So if warnings are a problem, then maybe we should do something about
> that? That's a
> possibility. Some better form of @SuppressWarnings might be helpful. More
> flexible
> control over what warnings javac emits might be useful too.
>
> (Somebody will inevitably suggest a different annotation that doesn't
> generate
> warnings. That would be incorrect, because the policy of how to handle
> usage of
> deprecated APIs, and whether warnings should be emitted, should be in the
> hands of
> the maintainers of the code that uses those APIs, not the API designers.)
>
> s'marks
>
>
>
> On 5/7/22 7:36 PM, Victor Williams Stafusa da Silva wrote:
> > The java.time package was released in Java 8, far back in 2014, more
> than 8
> > years ago. It has been a long time since then. Before that, we had the
> > dreadful infamous java.util.Date, java.util.Calendar,
> > java.text.DateFormat and their subclasses java.sql.Date, java.sql.Time,
> > java.sql.Timestamp, java.util.GregorianCalendar,
> java.text.SimpleDateFormat
> > and a few other lesser-known obscure cases.
> >
> > There are plenty of reasons to avoid using Date, Calendar, DateFormat and
> > their subclasses, otherwise there would be few to no reasons for
> java.time
> > to be conceived.
> >
> > Applications and libraries which used or relied on those legacy classes
> > already had plenty of time to move on and provide java.time.*
> alternatives.
> >
> > No skilled java programmer uses the legacy classes in new applications
> > except when integrating with legacy APIs.
> >
> > Using those classes nowadays should be considered at least a bad
> > programming practice, if not something worse (source of bugs, security
> > issues, etc).
> >
> > Novices, unskilled, careless and lazy programmers who should know better
> > still happily continue to use the legacy classes, pissing off those who
> are
> > more enlightened.
> >
> > So, my proposal is pretty simple: It is time to put a @Deprecated in all
> of
> > those (not for removal, though).
> >
> > First, let's deprecate all of them. Second, any method in the JDK
> returning
> > or receiving any of those as a parameter should be equally deprecated. If
> > there is no replacement method using the relevant classes or interfaces
> in
> > the java.time package, one should be created (which is something probably
> > pretty straightforward).
> >
> > If any of those methods is abstract or is part of an interface, then we
> > have a small problem, and it should be solved on a case-by-case analysis,
> > preferentially by providing a default implementation. I'm sure that some
> > cases should still exist, but I doubt that any of them would be a
> > showstopper.
> >
> > The negative impact is expected to be very small. Popular products like
> > Spring and Jakarta either already moved on and provided java.time.*
> > alternatives to their APIs or could do that quickly and easily. Anyone
> who
> > is left behind, would only get some [deserved] deprecation warnings.
> >
> > On the positive impact side, more than just discouraging the usage of the
> > ugly and annoying API of Date, Calendar and DateFormat for people who
> > should know better, those classes are a frequent source of bugs that are
> > hard do track and to debug due to their mutability and thread unsafety.
> > Thus, we are already way past the time to make the compiler give a
> warning
> > to anyone still using them.
> >
> > What do you think?
> >
>
More information about the discuss
mailing list