RFR: 8145461 changes to @Deprecated annotation

Stuart Marks stuart.marks at oracle.com
Wed Mar 30 01:44:08 UTC 2016



On 3/29/16 3:54 PM, Stephen Colebourne wrote:
> I am pleased to see the simpler form of the API move forward.

Great! Thanks for the quick review.

> However, I feel that condemed() as a boolean does not provide the key
> piece of information necessary - the expected version of removal. I
> would counter-propose that condemed() be replaced by
> expectedDeletion(), a String with the same version semantics as
> since(). While occasionally, the deletion version will be wrong or
> need to be pushed back, in most cases it will be correct. What it does
> do is provides a much better sense to users as to what is going to
> happen.
>
> @Deprecated(since="9", expectedDeletion="11)
> public void myBadBadMethod() {...}

Yes, this came up in the discussion after the JEP was initially posted in the 
Autumn of last year. We considered this, and in some draft APIs there was an 
element called "until" with semantics similar to what you suggest. Unfortunately 
it didn't make the cut. It turns out there are a bunch of problems with 
specifying and using such a thing in practice.

One issue is, how does one talk about the future? Two obvious answers are in 
terms of calendar dates and version numbers.

Martin's reply illustrates one issue with calendar dates.

Another issue with calendar dates is that, for the JDK, and many other projects, 
there are sustaining lines of development that overlap in time with 
feature-oriented lines of development. APIs would most likely be removed in the 
feature line, but not in a sustaining line, but you can't tell that by looking 
at a date. Or maybe it would be both, but you'd need more information to specify 
that.

The more likely alternative is to specify some kind of version string, either 
the first version where the removal is to occur, or the last version through 
which the condemned API is supported. This seems sensible enough, but I don't 
agree with the statement that "in most cases it will be correct."

Let's consider some "revisionist" history. :-)

Suppose we're working on JDK 1.6, we have the annotation with an 
expectedDeletion element, and we have an API we need to get rid of because it's 
incompatible with Jigsaw. We might therefore annotate the API as follows 
(remember, this is in JDK 1.6):

     @Deprecated(since="1.6", expectedDeletion="1.7")

There did end up being a 1.7 release ("Java 7") but didn't have Jigsaw in it as 
originally planned. [1] So we might decide to revise the annotation in 1.7 as 
follows:

     @Deprecated(since="1.6", expectedDeletion="1.8")

If this thing really conflicts with Jigsaw, which clearly didn't ship in 1.8, 
this would be wrong again. So in 1.8 we'd revise it once again:

     @Deprecated(since="1.6", expectedDeletion="1.9")

And now maybe this time it really will be removed. But the version number is 
wrong again; it's not "1.9" but instead according to JEP 223 [2] the version is 
now "9".

The changing of the expectedDeletion value undoubtedly will cause some temporary 
confusion. However, the main problem is that we've now littered the historical 
record with a bunch of misinformation. This has the potential to cause confusion 
for an indefinite period of time.

In addition, there is a general policy at Oracle against making any definite 
statements about future versions of products.

So, maybe this an Oracle-specific thing about not talking about the future, and 
maybe it's a JDK-specific thing that things change around so much from release 
to release. Shouldn't there be some provision for other libraries to specify 
information about the expected deletion version?

We considered that too. The problem is, as a matter of policy, the JDK wouldn't 
use it at all! For all deprecated APIs in the JDK, the expectedDeletion value 
would be the empty string. Now the problem is that the JDK is trying to define 
some attribute that it won't use itself, for external libraries to use. It might 
make sense if there were some clear consensus across different libraries about 
what could be put here, but I don't think there is. Should it be the first 
version where removal is expected? Or the last version there the API is 
guaranteed present? Or should be a date instead of a version?

Now the attribute is reduced to being a string in a library-specific format 
specifying some information with library-specific semantics. At that point it's 
adding so little value that it no longer belongs in the JDK.

If external libraries really want this, they can put this information in the 
javadoc text, or they can define their own annotations.

s'marks


[1] http://mreinhold.org/blog/rethinking-jdk7
[2] http://openjdk.java.net/jeps/223





More information about the jdk9-dev mailing list