<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p>Hi,</p>
<p>I don't think it's possible to give a custom warning at compile
time without the user having a specific annotation processor
active (ie, to get the warning, they'd first need to set up an
annotation processor which FX provides). The problem here is that
we can't enforce the use of the annotation processor
unconditionally.</p>
<p>The only annotation that you can use to intentionally create a
compiler warning is the @Deprecated annotation (perhaps the
compiler team should look into more annotations for this purpose).</p>
<p>The deprecated annotation was used at the time of the first
preview features to indicate their status, from JEP-12:</p>
<p>
<blockquote type="cite"><span style="color: rgb(94, 108, 132);
font-family: "DejaVu Sans", sans-serif; font-size:
14px; font-style: normal; font-variant-ligatures: normal;
font-variant-caps: normal; font-weight: 400; letter-spacing:
normal; orphans: 2; text-align: left; text-indent: 0px;
text-transform: none; widows: 2; word-spacing: 0px;
-webkit-text-stroke-width: 0px; white-space: normal;
background-color: rgb(255, 255, 255);
text-decoration-thickness: initial; text-decoration-style:
initial; text-decoration-color: initial; display: inline
!important; float: none;">The earliest version of this JEP
proposed to use the deprecation mechanism for flagging APIs
associated with preview features. Consequently, in Java SE 12
and 13, the APIs associated with preview features were
terminally deprecated at birth, that is, annotated with<span> </span></span><code
class="prettyprint" style="font-family: SFMono-Medium,
"SF Mono", "Segoe UI Mono", "Roboto
Mono", "Ubuntu Mono", Menlo, Courier,
monospace; color: rgb(94, 108, 132); font-size: 14px;
font-style: normal; font-variant-ligatures: normal;
font-variant-caps: normal; font-weight: 400; letter-spacing:
normal; orphans: 2; text-align: left; text-indent: 0px;
text-transform: none; widows: 2; word-spacing: 0px;
-webkit-text-stroke-width: 0px; white-space: normal;
background-color: rgb(255, 255, 255);
text-decoration-thickness: initial; text-decoration-style:
initial; text-decoration-color: initial;">@Deprecated(forRemoval=true,
since=...)</code><span style="color: rgb(94, 108, 132);
font-family: "DejaVu Sans", sans-serif; font-size:
14px; font-style: normal; font-variant-ligatures: normal;
font-variant-caps: normal; font-weight: 400; letter-spacing:
normal; orphans: 2; text-align: left; text-indent: 0px;
text-transform: none; widows: 2; word-spacing: 0px;
-webkit-text-stroke-width: 0px; white-space: normal;
background-color: rgb(255, 255, 255);
text-decoration-thickness: initial; text-decoration-style:
initial; text-decoration-color: initial; display: inline
!important; float: none;"><span> </span>when they were
introduced. For example, Java SE 13 declared an<span> </span></span><a
href="https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/lang/String.html#stripIndent%28%29"
class="external-link" target="_blank" rel="nofollow noopener"
title="Follow link" style="color: rgb(0, 82, 204);
text-decoration: var(--aui-link-decoration); cursor: pointer;
font-family: "DejaVu Sans", sans-serif; font-size:
14px; font-style: normal; font-variant-ligatures: normal;
font-variant-caps: normal; font-weight: 400; letter-spacing:
normal; orphans: 2; text-align: left; text-indent: 0px;
text-transform: none; widows: 2; word-spacing: 0px;
-webkit-text-stroke-width: 0px; white-space: normal;
background-color: rgb(255, 255, 255);">essential API
associated with text blocks</a><span style="color: rgb(94,
108, 132); font-family: "DejaVu Sans", sans-serif;
font-size: 14px; font-style: normal; font-variant-ligatures:
normal; font-variant-caps: normal; font-weight: 400;
letter-spacing: normal; orphans: 2; text-align: left;
text-indent: 0px; text-transform: none; widows: 2;
word-spacing: 0px; -webkit-text-stroke-width: 0px;
white-space: normal; background-color: rgb(255, 255, 255);
text-decoration-thickness: initial; text-decoration-style:
initial; text-decoration-color: initial; display: inline
!important; float: none;">, and a<span> </span></span><a
href="https://docs.oracle.com/en/java/javase/13/docs/api/jdk.compiler/com/sun/source/tree/SwitchExpressionTree.html"
class="external-link" target="_blank" rel="nofollow noopener"
title="Follow link" style="color: rgb(0, 82, 204);
text-decoration: var(--aui-link-decoration); cursor: pointer;
font-family: "DejaVu Sans", sans-serif; font-size:
14px; font-style: normal; font-variant-ligatures: normal;
font-variant-caps: normal; font-weight: 400; letter-spacing:
normal; orphans: 2; text-align: left; text-indent: 0px;
text-transform: none; widows: 2; word-spacing: 0px;
-webkit-text-stroke-width: 0px; white-space: normal;
background-color: rgb(255, 255, 255);">reflective API
associated with switch expressions</a><span style="color:
rgb(94, 108, 132); font-family: "DejaVu Sans",
sans-serif; font-size: 14px; font-style: normal;
font-variant-ligatures: normal; font-variant-caps: normal;
font-weight: 400; letter-spacing: normal; orphans: 2;
text-align: left; text-indent: 0px; text-transform: none;
widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;
white-space: normal; background-color: rgb(255, 255, 255);
text-decoration-thickness: initial; text-decoration-style:
initial; text-decoration-color: initial; display: inline
!important; float: none;">. However, the deprecation-based
approach was eventually dropped because it was confusing to
see an API element introduced in the same Java SE release as
it was deprecated, that is, to see<span> </span></span><code
class="prettyprint" style="font-family: SFMono-Medium,
"SF Mono", "Segoe UI Mono", "Roboto
Mono", "Ubuntu Mono", Menlo, Courier,
monospace; color: rgb(94, 108, 132); font-size: 14px;
font-style: normal; font-variant-ligatures: normal;
font-variant-caps: normal; font-weight: 400; letter-spacing:
normal; orphans: 2; text-align: left; text-indent: 0px;
text-transform: none; widows: 2; word-spacing: 0px;
-webkit-text-stroke-width: 0px; white-space: normal;
background-color: rgb(255, 255, 255);
text-decoration-thickness: initial; text-decoration-style:
initial; text-decoration-color: initial;">@since 13</code><span
style="color: rgb(94, 108, 132); font-family: "DejaVu
Sans", sans-serif; font-size: 14px; font-style: normal;
font-variant-ligatures: normal; font-variant-caps: normal;
font-weight: 400; letter-spacing: normal; orphans: 2;
text-align: left; text-indent: 0px; text-transform: none;
widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;
white-space: normal; background-color: rgb(255, 255, 255);
text-decoration-thickness: initial; text-decoration-style:
initial; text-decoration-color: initial; display: inline
!important; float: none;"><span> </span>and<span> </span></span><code
class="prettyprint" style="font-family: SFMono-Medium,
"SF Mono", "Segoe UI Mono", "Roboto
Mono", "Ubuntu Mono", Menlo, Courier,
monospace; color: rgb(94, 108, 132); font-size: 14px;
font-style: normal; font-variant-ligatures: normal;
font-variant-caps: normal; font-weight: 400; letter-spacing:
normal; orphans: 2; text-align: left; text-indent: 0px;
text-transform: none; widows: 2; word-spacing: 0px;
-webkit-text-stroke-width: 0px; white-space: normal;
background-color: rgb(255, 255, 255);
text-decoration-thickness: initial; text-decoration-style:
initial; text-decoration-color: initial;">@Deprecated(forRemoval=true,
since="13")</code><span style="color: rgb(94, 108, 132);
font-family: "DejaVu Sans", sans-serif; font-size:
14px; font-style: normal; font-variant-ligatures: normal;
font-variant-caps: normal; font-weight: 400; letter-spacing:
normal; orphans: 2; text-align: left; text-indent: 0px;
text-transform: none; widows: 2; word-spacing: 0px;
-webkit-text-stroke-width: 0px; white-space: normal;
background-color: rgb(255, 255, 255);
text-decoration-thickness: initial; text-decoration-style:
initial; text-decoration-color: initial; display: inline
!important; float: none;"><span> </span>on the same API
element.</span></blockquote>
The PreviewFeature annotation can't be used I think, it's part of
`jdk.internal.javac`.<br>
</p>
<p>--John</p>
<div class="moz-cite-prefix">On 07/02/2024 13:21, Kevin Rushforth
wrote:<br>
</div>
<blockquote type="cite"
cite="mid:010b221f-e06c-42eb-87c4-17a7584d4cae@oracle.com">Yes,
something like an opt-in property might be workable and is worth
considering. We would also want to explore ideas for producing a
compile-time warning along with with a pattern to document them.
I'm not familiar enough with what you can do with annotations, but
maybe there is something there that could help.
<br>
<br>
We should explore this further for JavaFX 23.
<br>
<br>
-- Kevin
<br>
<br>
<br>
On 2/7/2024 1:22 AM, John Hendrikx wrote:
<br>
<blockquote type="cite">Hi Kevin, Michael,
<br>
<br>
I think throwing an exception when using features that are
preview without a prerequisite property being present or set to
some value would be a good idea. JavaFX has quite a few
properties already, and a special one for previews would make it
possible to ensure that such a feature is not being used without
being aware of it.
<br>
<br>
I would suggest making the property consists of keys (comma
separated) so you must opt-in to each preview feature
separately, or having multiple properties that follow a specific
pattern.
<br>
<br>
A preview check can be as simple as:
<br>
<br>
if
(!Boolean.getProperty("javafx.enablePreview.platformPrefs") )
throw new UnsupportedOperationException(STANDARD_DISCLAIMER +
"preview feature, please enable: xyz");
<br>
<br>
The disclaimer can be a standard piece of text explaining what a
preview feature is, what it means, and what guarantees we offer
(as limited as they might be). For example, I think preview
features are still guaranteed to be maintained for the release
version they target, but that may be altered or completely
removed in a next major release.
<br>
<br>
I think a warning line is insufficient, especially when preview
feature use may be inherited via a dependency.
<br>
<br>
--John
<br>
<br>
On 07/02/2024 02:06, Michael Strauß wrote:
<br>
<blockquote type="cite">Hi Kevin,
<br>
<br>
my suggestion would be to annotate and document the preview
API (at
<br>
least annotations do show up by default in most IDEs), and
emit a
<br>
one-time runtime warning when the API is used (this works for
methods
<br>
and constructors). This would make it quite visible to
developers that
<br>
they are using a preview feature, or that a third-party
library uses a
<br>
preview feature.
<br>
<br>
The runtime warning can be suppressed with a command line
parameter
<br>
such as "javafx.enablePreviewFeatures". A more drastic
approach would
<br>
be to throw an exception from new APIs when the parameter is
not
<br>
specified.
<br>
<br>
Given that there are very tangible benefits to previewing new
API,
<br>
this would seem to me like a good enough solution.
<br>
<br>
<br>
On Wed, Feb 7, 2024 at 12:59 AM Kevin Rushforth
<br>
<a class="moz-txt-link-rfc2396E" href="mailto:kevin.rushforth@oracle.com"><kevin.rushforth@oracle.com></a> wrote:
<br>
<blockquote type="cite">In order for preview features and
incubating features to not cause more
<br>
problems than they solve, there needs to be a robust way to
ensure that
<br>
applications and libraries don't use them without knowing
that they are
<br>
doing so. We know how to do that for a feature that lives in
its own
<br>
module (an incubating feature), but not how to do that for
something
<br>
like a preview feature.
<br>
<br>
For incubating features, this is relatively
straight-forward, since they
<br>
are delivered in a separate module that has "incubator" in
the name,
<br>
isn't resolved by default, and warns you at runtime when
those modules
<br>
are resolved. Adapting what the JDK does for JavaFX should
be pretty
<br>
easy, and retain the benefit that an app knows when they are
using
<br>
incubating features.
<br>
<br>
I don't think it is feasible to do the same thing for
preview features.
<br>
The way the JDK preview features work is that a command line
option is
<br>
needed both at compile time and at runtime to opt into
preview features
<br>
for a specific release. This prevents using a preview API
from an
<br>
existing module and package without knowing that it is
subject to
<br>
change. Without a clear "opt in" mechanism to be able to use
an API, an
<br>
app would be able to accidentally use a feature whose API is
unstable
<br>
and quite possible might change. An annotation isn't good
enough (and
<br>
documentation certainly isn't sufficient). IDEs will still
autocomplete
<br>
and show the API, and once an app uses it -- accidentally or
otherwise
<br>
-- there is no indication at runtime that you are using a
feature that
<br>
will likely stop working without any notice in the next
version.
<br>
<br>
I don't see a good way to do this for JavaFX given the
limitations.
<br>
<br>
-- Kevin
<br>
</blockquote>
</blockquote>
</blockquote>
<br>
</blockquote>
</body>
</html>