2013/3/4 2:58 -0800, joe.da...@oracle.com: > On 02/28/2013 11:31 AM, mark.reinh...@oracle.com wrote: >> 2013/2/23 5:10 -0800, joe.da...@oracle.com: >>> 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 >> annotation? > > @Deprecated generally applies to all clients of an API. I don't think > people tend to associate potential removal of an API with deprecation > because we haven't (yet) removed any deprecated Java SE APIs from the > platform since to date we have placed a higher value on preserving > binary compatibility.
I'm continually surprised by developers I meet at conferences who (sometimes angrily) demand that deprecated APIs be removed, so I think the reality is a mixed bag -- not that it matters a great deal either way. What I'm trying to understand is, for a JDK API that's @Supported(true) in one or more releases, what's the recommended protocol for removing it? Perhaps something like this? @Supported(true) @Supported(true) @Deprecated @Supported(false) <gone> (Time flows downward.) Or does @Supported(false) happen when @Deprecated is applied? Or will usage vary? > The deprecated-in-JDK-7 and JDK-specific apt API was removed in JDK 8, > but that is the only removal of a deprecated API from the JDK I'm aware > of offhand. I suspect that's correct. > The jdk.Supported annotation is mostly a statement to users outside of > the JDK itself. Understood. >> ... >> >> 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. > > If a package has a mixture of supported and non-supported types, I would > say it should either *not* have a @jdk.Supported annotation itself, or > if the types in the package were predominately one value or another, > then the package annotation should match the prevailing value of the types. > > Since types have a more concrete existence then packages, I regard the > jdk.Supported information on package-info files to have a higher mixture > of informative versus normative sentiment compared to the annotation on > types. If we're going to go to the trouble of defining an annotation for this, and then sprinkle that annotation throughout our code, shouldn't we give it as precise a meaning as possible? It'd be a shame for @Supported (or whatever it turns out to be) to have no more authoritative value than, say, the @since javadoc tag. >>> ... >> >> 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? > > The ct.sym mechanism we have today is compile-time only and the > mechanism and all its warnings can be circumvented by adding a single > option to javac; the option is described on stackoverflow, amongst other > places. Therefore, it is fairly easy for someone to claim "but I didn't > know" in regards to the status of a JDK-specific API. Well, sure. > Since any jdk.Supported annotations applied to types are more localized > and more specific ("*this* type is or is not supported / stable / etc.") > it is both easier for JDK developers to made incremental changes to the > JDK code base and is it also easier for users of those types to see what > is going on since any inspection of the types can reveal the annotation > value. Agreed, but I was trying to understand how the annotation-based system would be harder to "cirvumvent", at either compile time or run time. >> ... >> >> 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. > > Technically, it would be possible to evolve a boolean-valued annotation > to one that included a non-boolean value as well by adding a new method > that had a default to the annotation type. For example > > // Version 1 > @interfaced Supported { > boolean value() default true; > } > > // Version 2 > @interface Supported { > boolean value() default true; > Stability stability() default STABLE; > } Yuck. > However, if what we eventually want to capture is "stability level" > rather than supported-ness than having a single stability value from the > start would of course be preferable. > > That said, it terms of the exercise of going over the inventory of > existing types, I think it can be helpful to at first be constrained to > making a binary supported / not-supported determination to avoid the > temptation to overuse a middle-of-the-road value like EVOLVING. > > Types that don't fit well into supported / not-supported classification > can help drive what other distinctions are useful to make. Agreed. >>>> - 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? > > Allowing class loaders and other run-time tools to query the annotation > value and take some action, like log a warning or potentially refuse to > link. Okay, that sounds plausible. > ... > > As an aside, going forward I think we should make greater use of the > "jdk.*" namespace for JDK-specific types. The JDK codebase has outlasted > Sun Microsystems (R.I.P.) and therefore the natural lifetime of > "com.sun.*." APIs. The JDK has also outlasted both of Sun Microsystems' > ticker symbols (SUNW, and JAVA); as I understand their conventions, > ticker symbols are a preferred component of Solaris package names. The > "jdk" name will be appropriate as long as the JDK is around. I have long supported this position -- jdk.* is the place to be for new non-Platform, non-proprietary APIs. >> 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. > > As covered in other responses, while the jdk repo is the natural home, > langtools was for bootstrapping reasons. Hmm. Okay. - Mark