@Supported design issues

mark.reinhold at oracle.com mark.reinhold at oracle.com
Thu Feb 28 19:31:21 UTC 2013

2013/2/23 5:10 -0800, joe.darcy at oracle.com:
> On 2/22/2013 3:04 PM, mark.reinhold at oracle.com wrote:
>> ...
>> - The annotation isn't a simple marker annotation, which is what I
>> expected at first glance; it takes a boolean parameter.  Does this
>> mean that we have to go add "@Supported(false)" to everything that's
>> not supported?  I'd have thought that anything not marked
>> "@Supported(true)" would by implication, well, not be supported.
>> Does it mean that if I mark a package "@Supported(true)" I can use
>> "@Supported(false)" on some of its member types?
> Having Supported take a boolean value both allows the explicit statement 
> that an item is not supported as well as providing a possible transition 
> path from Supported(true) to Supported(false) to removed.

Okay.  In that scenario what's the role of the existing @Deprecated

> We already have types in the JDK whose comments explicitly say "this is 
> not part of any supported API" (much of javac).
> If there is no explicit opt-in to mark supportedness as well as 
> non-supportedness in my estimation that means the status of all the 
> unadorned APIs is uncertain: "Perhaps this interesting API was just 
> overlooked in being marked supported, I'll go ahead and us it anyway..."

Okay, so that will give us a three-valued system:

  - @Supported(true) -- supported
  - @Supported(false) -- not supported
  - No @Supported annotation -- unknown (but probably not supported)

I'm still wondering whether marking a package "@Supported(true)" means
that I can use "@Supported(false)" on some of its member types.  That
would be convenient for cases such as the JMX OSMBeanFactory class that
Alan mentioned.

Earlier in this thread you stated "@Supported(true)" is meant to convey
the same conservative evolution policy as is implicit in the SE APIs.
It would be good for that policy to be captured in the specification of
the annotation itself.

>> - Is the "supportedness" of a package inherited by its sub-packages?
> No; for at least two reasons. First, annotation inheritance is only 
> defined to work for classes along the superclass chain; there is no 
> defined inheritance of annotations on methods or from superinterfaces. 
> Second, subpackages of a package can have at most a tenuous logical 
> relationship to the parent package (and they have no additional 
> language-level access). ...

I understand both those points -- I was just wondering whether you
intended to layer additional informal inheritance semantics over and
above those of the language.  I agree that's it's better not to do so,
at least not for packages.

>> - The name "Supported" is problematic.  It begs the question,
>> "Supported by whom?"  Maybe the annotation should take URL and
>> phone-number parameters so that you know where to go when you run
>> into a problem?
> I would trust that users of a JDK distribution would by default turn to 
> the provider of their distribution for support, or barring that, 
> stackoverflow.

Let's leave this bikeshed issue for later ...

>> - I agree with Martin that "supportedness", in the abstract, isn't a
>> binary thing.  If we're going to define an annotation for broad use
>> then we should at least consider a metric with more than two values.
>> ...
> The status quo today and for the last 15 years has been often sloppy 
> management of the types in com.sun.* Some of them are 
> supported/stable/official/whatever others are not. Which are which is 
> not clear. The closest mechanism to documenting this, aside what 
> whatever comments might be in the code and the few subsets with 
> published javadoc, are whether or not the types ends up in ct.sym 
> proto-module system and if it does, whether or not a warning is issued 
> when using the type.
> The ct.sym file is constructed by passing information from the docs make 
> target to a program living in the langtools repo. So today the mechanism 
> we have is a very an obscure system that does a poor job of conveying 
> this kind of information and is easy to circumvent.

What we have today is certainly a maintenance headache for JDK
developers, who have to understand the obscure makefiles involved in
the construction of ct.sym.

Between compile-time warnings and controlling javadoc output, however,
I'd say that it does an okay job of conveying the "supportedness" of
JDK-specific APIs to the rest of the world, though it could be better.

What I don't understand is how doing all this with an annotation would
be any harder to circumvent than what we have today.  Are you proposing
to do something stronger than issue a compiler warning when people try
to use an unsupported API?

> If we go from that obscure system to an explicit boolean-valued 
> annotation, that is in my estimation a vast improvement both in clarity 
> and usability.

I agree that it's an improvement, in that it makes it easier for tools
beyond javac to determine the "supportedness" of an API.  I can well
imagine IDEs leveraging this annotation to give advice to developers
ahead of compile time.

Do you plan to change the makefiles for ct.sym, and the non-SE javadoc,
so that it's based on the new annotation rather than today's obscure
{,NON_}CORE_PKGS.gmk files?  Otherwise the maintenance headache will
just get worse.

>> These are, more or less, the Solaris "Stable", "Evolving",
>> "Unstable", and "Internal" levels, which suggests a single
>> "@Stability" annotation and an enum parameter with the values
> As I indicated earlier in this thread, I agree there are more subtle 
> distinctions that can be of interest, but at times the better is the 
> enemy of the good and the first approximation of is this type or package 
> supported or not is a huge improvement of what we have today even if it 
> doesn't cover all the possible gradations.

The better can be the enemy of the good, yet the expedient can be the
enemy of the future.

If we're going to define a new annotation with this much visibility then
we should at least take the time to inventory the JDK-specific APIs that
we have, and those we reasonably expect to have in the near future, to
understand how many distinct levels are useful.

Would it make sense, e.g., for the streams SPI in Lambda to be marked
"unstable" rather than "not supported", so that javadoc for it is
generated yet no commitment is made to its current form?

Even if we think we only need two explicit levels today, a design that
admits expansion is preferable to one that forever limits us to just two
values.  An annotation that takes an enum, to which we can add values
over time, would be more future-proof.

>> - The retention policy of the annotation is RUNTIME.  Is that really
>> what we want?  I'd have expected CLASS.
> CLASS is not very helpful (and certainly not a helpful default). A 
> CLASS-retention annotation can be reliably used at the compile-time of 
> other code. For the use case of Supported, I think it is more helpful to 
> allow runtime querying of the property.

What run-time use cases do you have in mind?

>> - The annotation is in the top-level "jdk" package.  What's the
>>   rationale for this?  I'd have expected it to be defined in
>>   "jdk.annotations", so that if and when other JDK-specific
>>   annotations arise we have one convenient place to find them,
>>   and only them.
> There are 81 subtypes of java.lang.annotation.Annotation listed in JDK 8 b77
> ...
> That gives a total of 42 annotation types defined in packages ending 
> with "annotation" or about half of them. However, I would discount 
> java.lang.annotation and javax.xml.bind.annotation as outliers, in which 
> case most JDK annotations are *not* in a dedicated package.
> I think it is usually not helpful to segregate annotation types into 
> dedicated packages, after all we don't have "enums", "interfaces", and 
> "classes" packages and there are nearly as many annotations defined 
> directly in java.lang (SuppressWarnings, Deprecated, Override, 
> SafeVarargs, etc.) as in java.lang.annotation. ...

Fair enough.  What struck me as odd about "jdk.Supported" is that it's
a type in a top-level package, which is not something we've ever had
before.  It's a bit jarring, though not illogical, so I suppose I can
get used to it.

I did just notice that the annotation's source file is in the langtools
repo rather than the jdk repo.  What's the rationale for that?  I think
most JDK developers would expect to find it in the jdk repo.

>> Finally, this annotation is intended for use throughout our code base,
>> and will be of interest not just to people working on the JDK but also
>> to people using it.  Its syntax, semantics, and intended usage should
>> hence be documented in a JEP, which will be much more visible than an
>> obscure Javadoc page.
> The listed criteria for a JEP are:
>> It requires two or more weeks of engineering effort,
>> It makes a significant change to the JDK, or to the processes and 
>> infrastructure by which it is developed, or
>> It is in high demand by developers or customers.
> Perhaps excluding this email thread, the first condition does not hold 
> for this work and the second two conditions are debatable.

You may disagree, but I think the second condition clearly holds.

> ...
> Given the apparent heightened  interest in this topic, I trust that if a 
> JEP for this is sent in, it will be promptly published in the JEP index.

Yes, of course.

- Mark

More information about the core-libs-dev mailing list