handling the deprecations introduced by early access builds 116 and 118 of jdk 9
Stuart Marks
stuart.marks at oracle.com
Wed Jun 1 00:34:25 UTC 2016
On 5/30/16 11:48 AM, Richard Hillegas wrote:
> Dalibor Topic recommended that I post this feedback on core-libs-dev. This is my
> feedback after ameliorating the deprecation warnings which surfaced when I
> compiled and tested Apache Derby with early access builds 116 and 118 of JDK 9.
> Derby is a pure Java relational database whose original code goes back almost 20
> years. Other large, old code bases (like Weblogic) may have similar experiences.
> More detail on my experience can be found on the JIRA issue which tracks the
> Derby community's attempt to keep our code evergreen against JDK 9:
> https://issues.apache.org/jira/browse/DERBY-6856
Hi Rick,
Thanks for your feedback on the API deprecations.
A couple notes on deprecation. First, the deprecation JEP (JEP 277) [1] has
clarified the definition of deprecation so that by default it no longer means
that the API will be removed. In the absence of forRemoval=true, deprecation is
merely a recommendation for code to migrate away from the annotated API. Only
when the forRemoval=true element is present does it mean that the API is
actually going to be removed. None of these deprecations has forRemoval=true,
this means that there's no great urgency for anyone to migrate away from them.
Now, they will generate compilation warnings, which is quite possibly a problem.
There are some existing mechanisms for disabling warnings, such as
-Xlint:-deprecation and the @SuppressWarnings annotation. These might not be
sufficient. We're considering adding some finer-grained mechanisms. Ideally, for
deprecated APIs that aren't being removed, it should be possible to manage the
warnings so that migration of any code base can proceed at whatever pace its
maintainers feel is appropriate, without it being forced by any particular JDK
release.
If you have any thoughts on how to better manage deprecation warnings, I'd love
to hear them.
> o Deprecating autoboxing constructors - Deprecating the autoboxing constructors
> for primitive wrapper objects caused a large rototill of Derby code. That
> rototill was comparable in size to the changes made necessary by Java 5's
> introduction of generics. Hopefully, IDEs can automate much of this chore.
The boxing constructors -- e.g., new Integer(432) -- are the ones being
deprecated. The preferred alternative is Integer.valueOf(432). Note that
*auto*boxing ends calling valueOf() under the covers. Autoboxing is generally
preferable, although not without pitfalls, such as the overloading of
List.remove(int) vs List.remove(Object), as you stumbled across in the
referenced bug report. Using valueOf() instead of autoboxing would have avoided
the error.
> o Deprecating Class.newInstance() - The deprecation of Class.newInstance()
> forced a similarly large rototill. The code became more verbose. Additional
> exceptions had to be caught and propagated up the call stack. For reasons which
> I don't understand, I had better luck using Class.getConstructor().newInstance()
> than Class.getDeclaredConstructor().newInstance(). But the former replacement
> code requires you to make constructors public. For some code bases, that may
> introduce security problems which are worse than the security problem being
> addressed by this deprecation. I hope that IDEs and the release notes for JDK 9
> will provide some guidance for how to handle these issues.
It would be good to understand why getDeclaredConstructor() didn't work. Clearly
requiring a public no-arg constructor is a non-starter.
> o Deprecating java.util.Observable and java.util.Observer - Two ameliorations
> are recommended at
> http://mail.openjdk.java.net/pipermail/core-libs-dev/2016-April/040436.html. The
> first suggestion (use the awt event model) runs very much counter to the whole
> intent of Jigsaw. That is because pulling in awt can bloat up an application
> with large, otherwise unneeded libraries. Using awt was out of the question for
> Derby, given that the community had already invested a great deal of effort in
> paring back Derby's dependencies in order to let the code run on JDK 8 compact
> profile 2. That left us with the other option: write your own replacement
> classes. If a lot of people end up having to write the same replacement code,
> then that argues for leaving this small but useful functionality in the JDK. I
> think that the people who advocated for this deprecation did not have good
> visibility into how widely these classes are being used in the wild. I recommend
> that this deprecation be re-evaluated.
Observable and Observer have a long history of problem reports and enhancement
requests that show that people want them to be something other than what they
are. This includes: Observable should be an interface, not an abstract class;
there is only one "changed" bit, without any notion of what has changed; there
is no control over what thread calls observers; there is no ability to control
sequence of calls to observers; change notifications aren't in one-for-one
correspondence with change updates; Observers are compared using equals() not
reference equality; and so forth.
The point of deprecating Observable/Observer is to tell people looking for some
event notification mechanism to avoid using this one, as it seems quite likely
that it won't satisfy their needs. It also tells current users that if they're
running into its shortcomings, they probably won't be addressed. The suggestion
of using java.beans properties as an alternative is there because the beans
notification model was developed to address many of the shortcomings of
Observable/Observer.
Of course beans doesn't work for everything. If Observable/Observer does exactly
what Derby needs, then Derby can continue to use it indefinitely. There's no
need to remove it.
s'marks
More information about the core-libs-dev
mailing list