PreviewFeature on packages and modules

classic Classic list List threaded Threaded
16 messages Options
Reply | Threaded
Open this post in threaded view
|

PreviewFeature on packages and modules

Nikita Eshkeev
The PreviewFeature (https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java) annotation can be applied to modules and packages. But I don't get any compile-time errors/warnings when I try to use code that is inside of either a package or a module that is annotated with PreviewFeature.
 
What I did
 
1. I added a new module to openjdk with the "jdk.neshkeev" name
2. I added module-info.java, package-info.java and MyPreviewClass.java (which is just an empty class)
3. I annotated both module-info.java and package-info.java with PreviewFeature
4. I exported jdk.internal.javac package to jdk.neshkeev in module-info.java of java.base
5. `make images` the jdk's source code
6. I created Main.java with the following content
class Main {
 {
   new jdk.neshkeev.MyPreviewClass();
 }
}
7. I compiled Main.java with my openjdk that was built in the step 5.
 
Here is the link to my openjdk fork with the jdk.neshkeev module: https://github.com/neshkeev/jdk
 
What is expected
 
Since MyPreviewClass is inside of the package that is annotated with PreviewFeature and it is also inside of the module that is also annotated with PreviewFeature I expect to get compile time errors/warnings. I believe that compile-time errors/warnings should arise since Main.java can't be considered as participating source code
 
What happened
 
No compile-time errors/warnings occurred
 
Is this a bug?
 
 
 
 
 
Reply | Threaded
Open this post in threaded view
|

Re: PreviewFeature on packages and modules

Alex Buckley-3
It looks like your neshkeev/jdk repo was forked from openjdk/jdk very
recently, so your compiler should have the latest support for preview
APIs. That support is specified at
https://bugs.openjdk.java.net/browse/JDK-8249554 -- when preview
features are enabled/disabled, no warning/error is due if "The
declaration where the use of a preview API element appears is within the
same module as the declaration of the preview API element."  This rule
reflects the JEP 12 policy you refer to, where source code in the same
module as a preview API is deemed as "participating" and causes no
warnings/errors.

I can't tell where your Main.java file lives at compile time, but
presumably you are not accidentally placing it in the jdk.neshkeev
module. Like you, I expect a warning/error for Main's reference to
MyPreviewClass, since Main is not participating in your preview API.

Alex

On 2/3/2021 8:00 AM, Nikita Eshkeev wrote:

> The PreviewFeature
> (https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java 
> <https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java>)
> annotation can be applied to modules and packages. But I don't get any
> compile-time errors/warnings when I try to use code that is inside of
> either a package or a module that is annotated with PreviewFeature.
> What I did
> 1. I added a new module to openjdk with the "jdk.neshkeev" name
> 2. I added module-info.java, package-info.java and MyPreviewClass.java
> (which is just an empty class)
> 3. I annotated both module-info.java and package-info.java with
> PreviewFeature
> 4. I exported jdk.internal.javac package to jdk.neshkeev in
> module-info.java of java.base
> 5. `make images` the jdk's source code
> 6. I created Main.java with the following content
> class Main {
>   {
>     new jdk.neshkeev.MyPreviewClass();
>   }
> }
> 7. I compiled Main.java with my openjdk that was built in the step 5.
> Here is the link to my openjdk fork with the jdk.neshkeev module:
> https://github.com/neshkeev/jdk <https://github.com/neshkeev/jdk>
> What is expected
> Since MyPreviewClass is inside of the package that is annotated with
> PreviewFeature and it is also inside of the module that is also
> annotated with PreviewFeature I expect to get compile time
> errors/warnings. I believe that compile-time errors/warnings should
> arise since Main.java can't be considered as participating source code
> What happened
> No compile-time errors/warnings occurred
> Is this a bug?
Reply | Threaded
Open this post in threaded view
|

Re: PreviewFeature on packages and modules

Nikita Eshkeev
Thank you, Alex, for your response, I should've expressed some points more clearly:

1. Yes, I did fork the openjdk/jdk just today, so your assumption is correct
2. The Main.java file is external to my jdk and the jdk is used to compile it

I haven't seen https://bugs.openjdk.java.net/browse/JDK-8249554 , but I've been perusing JEP-12 https://openjdk.java.net/jeps/12 for quite some time now and it says the following about the modules:

"To allow for intra-JDK use of a preview API, source code in the same module as a preview API is deemed to be "participating..."

I can only guess that "intra-JDK" here means that the module is used by other modules inside the JDK, the JEP doesn't mention how modules that are introduced as preview API (annotated with PreviewFeature) is used outside the JDK.

The JEP mentions that the code that is inside a package that is introduced as preview API is considered as participating and doesn't generate compile-time errors/warning, so I conclude that javac hasn't implemented this part yet, but it should.

03.02.2021, 20:54, "Alex Buckley" <[hidden email]>:

It looks like your neshkeev/jdk repo was forked from openjdk/jdk very
recently, so your compiler should have the latest support for preview
APIs. That support is specified at
https://bugs.openjdk.java.net/browse/JDK-8249554 -- when preview
features are enabled/disabled, no warning/error is due if "The
declaration where the use of a preview API element appears is within the
same module as the declaration of the preview API element." This rule
reflects the JEP 12 policy you refer to, where source code in the same
module as a preview API is deemed as "participating" and causes no
warnings/errors.

I can't tell where your Main.java file lives at compile time, but
presumably you are not accidentally placing it in the jdk.neshkeev
module. Like you, I expect a warning/error for Main's reference to
MyPreviewClass, since Main is not participating in your preview API.

Alex

On 2/3/2021 8:00 AM, Nikita Eshkeev wrote:

 The PreviewFeature
 (https://github.com/openjdk/jdk/blob/master/src/java.base/sha…
 <https://github.com/openjdk/jdk/blob/master/src/java.base/sha…>)
 annotation can be applied to modules and packages. But I don't get any
 compile-time errors/warnings when I try to use code that is inside of
 either a package or a module that is annotated with PreviewFeature.
 What I did
 1. I added a new module to openjdk with the "jdk.neshkeev" name
 2. I added module-info.java, package-info.java and MyPreviewClass.java
 (which is just an empty class)
 3. I annotated both module-info.java and package-info.java with
 PreviewFeature
 4. I exported jdk.internal.javac package to jdk.neshkeev in
 module-info.java of java.base
 5. `make images` the jdk's source code
 6. I created Main.java with the following content
 class Main {
   {
     new jdk.neshkeev.MyPreviewClass();
   }
 }
 7. I compiled Main.java with my openjdk that was built in the step 5.
 Here is the link to my openjdk fork with the jdk.neshkeev module:
 https://github.com/neshkeev/jdk <https://github.com/neshkeev/jdk>
 What is expected
 Since MyPreviewClass is inside of the package that is annotated with
 PreviewFeature and it is also inside of the module that is also
 annotated with PreviewFeature I expect to get compile time
 errors/warnings. I believe that compile-time errors/warnings should
 arise since Main.java can't be considered as participating source code
 What happened
 No compile-time errors/warnings occurred
 Is this a bug?



Reply | Threaded
Open this post in threaded view
|

Re: [External] : Re: PreviewFeature on packages and modules

Alex Buckley-3
On 2/3/2021 11:42 AM, Nikita Eshkeev wrote:

> I haven't seen https://bugs.openjdk.java.net/browse/JDK-8249554 , but
> I've been perusing JEP-12 https://openjdk.java.net/jeps/12 for quite
> some time now and it says the following about the modules:
>
> "To allow for intra-JDK use of a preview API, source code in the same
> module as a preview API is deemed to be "participating..."
>
> I can only guess that "intra-JDK" here means that the module is used by
> other modules inside the JDK, the JEP doesn't mention how modules that
> are introduced as preview API (annotated with PreviewFeature) is used
> outside the JDK.

JDK modules are relatively large and rich. It would be unfortunate if a
preview API in, say, java.base, couldn't be used elsewhere in java.base,
either in the implementation of a method within java.base or in the
public signature of some other exported API of java.base. (A flaw of
incubating APIs is that standard API signatures can't be enhanced to
accept and return classes of the incubating API. That limits exposure of
the incubating API, which means less feedback. Preview APIs, with their
greater claim to stability, appear in java.* packages and can thus
appear in standard API signatures.)

That's what the intra-JDK scenario is about -- use within the same
module. We might wish to expand the scenario in future, to allow use by
other JDK modules that have "some" relationship with the declaring
module, but that's not been shown to be necessary yet.

I'm not sure what you mean by "the JEP doesn't mention how modules that
are introduced as preview API is used outside the JDK". A preview API is
defined to include a module or a package, not just a class or interface,
so any use of an @PreviewFeature module by non-participating source code
should trigger the warning/error described in "Use of Preview Features".
Whether the non-participating source code is in some other java.*
module, or in some jdk.* module, or in some user module doesn't matter.

> The JEP mentions that the code that is inside a package that is
> introduced as preview API is considered as participating and doesn't
> generate compile-time errors/warning, so I conclude that javac hasn't
> implemented this part yet, but it should.

Right.

Alex

> 03.02.2021, 20:54, "Alex Buckley" <[hidden email]>:
>
>     It looks like your neshkeev/jdk repo was forked from openjdk/jdk very
>     recently, so your compiler should have the latest support for preview
>     APIs. That support is specified at
>     https://bugs.openjdk.java.net/browse/JDK-8249554
>     <https://bugs.openjdk.java.net/browse/JDK-8249554> -- when preview
>     features are enabled/disabled, no warning/error is due if "The
>     declaration where the use of a preview API element appears is within
>     the
>     same module as the declaration of the preview API element." This rule
>     reflects the JEP 12 policy you refer to, where source code in the same
>     module as a preview API is deemed as "participating" and causes no
>     warnings/errors.
>
>     I can't tell where your Main.java file lives at compile time, but
>     presumably you are not accidentally placing it in the jdk.neshkeev
>     module. Like you, I expect a warning/error for Main's reference to
>     MyPreviewClass, since Main is not participating in your preview API.
>
>     Alex
>
>     On 2/3/2021 8:00 AM, Nikita Eshkeev wrote:
>
>           The PreviewFeature
>           (https://github.com/openjdk/jdk/blob/master/src/java.base/sha…
>         <https://urldefense.com/v3/__https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java__;!!GqivPVa7Brio!LxjKv9JdKyJ8GVP6bYd5mhzj4IQaifeEJOjjdwfCgrWzJ5_pgydVKDGFKjP3a0N-3Us$>
>
>           <https://github.com/openjdk/jdk/blob/master/src/java.base/sha…
>         <https://urldefense.com/v3/__https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java__;!!GqivPVa7Brio!LxjKv9JdKyJ8GVP6bYd5mhzj4IQaifeEJOjjdwfCgrWzJ5_pgydVKDGFKjP3a0N-3Us$>>)
>
>           annotation can be applied to modules and packages. But I don't
>         get any
>           compile-time errors/warnings when I try to use code that is
>         inside of
>           either a package or a module that is annotated with
>         PreviewFeature.
>           What I did
>           1. I added a new module to openjdk with the "jdk.neshkeev" name
>           2. I added module-info.java, package-info.java and
>         MyPreviewClass.java
>           (which is just an empty class)
>           3. I annotated both module-info.java and package-info.java with
>           PreviewFeature
>           4. I exported jdk.internal.javac package to jdk.neshkeev in
>           module-info.java of java.base
>           5. `make images` the jdk's source code
>           6. I created Main.java with the following content
>           class Main {
>             {
>               new jdk.neshkeev.MyPreviewClass();
>             }
>           }
>           7. I compiled Main.java with my openjdk that was built in the
>         step 5.
>           Here is the link to my openjdk fork with the jdk.neshkeev module:
>         https://github.com/neshkeev/jdk
>         <https://urldefense.com/v3/__https://github.com/neshkeev/jdk__;!!GqivPVa7Brio!LxjKv9JdKyJ8GVP6bYd5mhzj4IQaifeEJOjjdwfCgrWzJ5_pgydVKDGFKjP3fmAa7N8$>
>         <https://github.com/neshkeev/jdk
>         <https://urldefense.com/v3/__https://github.com/neshkeev/jdk__;!!GqivPVa7Brio!LxjKv9JdKyJ8GVP6bYd5mhzj4IQaifeEJOjjdwfCgrWzJ5_pgydVKDGFKjP3fmAa7N8$>>
>           What is expected
>           Since MyPreviewClass is inside of the package that is
>         annotated with
>           PreviewFeature and it is also inside of the module that is also
>           annotated with PreviewFeature I expect to get compile time
>           errors/warnings. I believe that compile-time errors/warnings
>         should
>           arise since Main.java can't be considered as participating
>         source code
>           What happened
>           No compile-time errors/warnings occurred
>           Is this a bug?
>
>
>
>
Reply | Threaded
Open this post in threaded view
|

Re: PreviewFeature on packages and modules

Jan Lahoda
In reply to this post by Alex Buckley-3
On 03. 02. 21 18:54, Alex Buckley wrote:

> It looks like your neshkeev/jdk repo was forked from openjdk/jdk very
> recently, so your compiler should have the latest support for preview
> APIs. That support is specified at
> https://bugs.openjdk.java.net/browse/JDK-8249554 -- when preview
> features are enabled/disabled, no warning/error is due if "The
> declaration where the use of a preview API element appears is within
> the same module as the declaration of the preview API element."  This
> rule reflects the JEP 12 policy you refer to, where source code in the
> same module as a preview API is deemed as "participating" and causes
> no warnings/errors.
>
> I can't tell where your Main.java file lives at compile time, but
> presumably you are not accidentally placing it in the jdk.neshkeev
> module. Like you, I expect a warning/error for Main's reference to
> MyPreviewClass, since Main is not participating in your preview API.


One thing to note here is e.g. @Deprecated on a package does not
automatically deprecate the classes belonging to the given package.
Here, we have a package annotated with @PreviewFeature, but not a class
annotated as a preview feature, and the preview flag is not propagated
from packages to classes, similarly to the deprecated flag. But we can
surely make this particular flag to propagate to the classes in the
package, if desired.

Jan

>
> Alex
>
> On 2/3/2021 8:00 AM, Nikita Eshkeev wrote:
>> The PreviewFeature
>> (https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java 
>> <https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java>)
>> annotation can be applied to modules and packages. But I don't get
>> any compile-time errors/warnings when I try to use code that is
>> inside of either a package or a module that is annotated with
>> PreviewFeature.
>> What I did
>> 1. I added a new module to openjdk with the "jdk.neshkeev" name
>> 2. I added module-info.java, package-info.java and
>> MyPreviewClass.java (which is just an empty class)
>> 3. I annotated both module-info.java and package-info.java with
>> PreviewFeature
>> 4. I exported jdk.internal.javac package to jdk.neshkeev in
>> module-info.java of java.base
>> 5. `make images` the jdk's source code
>> 6. I created Main.java with the following content
>> class Main {
>>   {
>>     new jdk.neshkeev.MyPreviewClass();
>>   }
>> }
>> 7. I compiled Main.java with my openjdk that was built in the step 5.
>> Here is the link to my openjdk fork with the jdk.neshkeev module:
>> https://github.com/neshkeev/jdk <https://github.com/neshkeev/jdk>
>> What is expected
>> Since MyPreviewClass is inside of the package that is annotated with
>> PreviewFeature and it is also inside of the module that is also
>> annotated with PreviewFeature I expect to get compile time
>> errors/warnings. I believe that compile-time errors/warnings should
>> arise since Main.java can't be considered as participating source code
>> What happened
>> No compile-time errors/warnings occurred
>> Is this a bug?
Reply | Threaded
Open this post in threaded view
|

Re: PreviewFeature on packages and modules

Alex Buckley-3
On 2/3/2021 1:30 PM, Jan Lahoda wrote:
> One thing to note here is e.g. @Deprecated on a package does not
> automatically deprecate the classes belonging to the given package.
> Here, we have a package annotated with @PreviewFeature, but not a class
> annotated as a preview feature, and the preview flag is not propagated
> from packages to classes, similarly to the deprecated flag. But we can
> surely make this particular flag to propagate to the classes in the
> package, if desired.

Thanks for the info. I agree that a package being annotated with
@PreviewFeature is misleading, since like package deprecation, it's a
no-op. However, a module being annotated with @PreviewFeature ought to
have a visible effect if another module `requires` it. If Nikita puts
Main.java in a module that `requires jdk.neshkeev`, then I'd expect a
warning/error.

This thread is really about whether explicitly designating a module as a
preview API implicitly designates every class within the module as a
preview API. JEP 12 doesn't directly answer that question. It only says
that every class within the preview module is "participating", and what
happens if a class _explicitly_ designated as preview is used by other code.

The other way of asking the question is: Should a preview module be able
to contain non-preview classes? (Where every preview class in the module
would be marked with @PreviewFeature, and any class not so marked would
be non-preview.)  First issue: you could "silently" use such non-preview
classes from code on the classpath without a `requires` clause to
trigger a warning/error for use of the preview module itself. This
"silent" use feels undesirable, given the preview module's non-final
status.  Second issue: preview classes and non-preview classes could
live in the same package (since preview classes aren't forced into a
dedicated namespace like incubating classes) -- that's legitimate when a
few preview classes are added to a classic package in java.base, but we
didn't really envisage a handful of non-preview classes hanging out in a
vast crowd of preview classes in a preview module.

In sum, there's a strong case for saying that everything in a preview
module has preview status. (Where marking anything in the module with
@PreviewFeature is legal but redundant.) This would be convenient for
preview API designers, who could write @PreviewFeature once and have it
trickle down.

I suspect this is either very painful to implement in javac/javadoc, or
very easy. Jan, please tell us which! :-)

Alex

>> On 2/3/2021 8:00 AM, Nikita Eshkeev wrote:
>>> The PreviewFeature
>>> (https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java 
>>> <https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java>)
>>> annotation can be applied to modules and packages. But I don't get
>>> any compile-time errors/warnings when I try to use code that is
>>> inside of either a package or a module that is annotated with
>>> PreviewFeature.
>>> What I did
>>> 1. I added a new module to openjdk with the "jdk.neshkeev" name
>>> 2. I added module-info.java, package-info.java and
>>> MyPreviewClass.java (which is just an empty class)
>>> 3. I annotated both module-info.java and package-info.java with
>>> PreviewFeature
>>> 4. I exported jdk.internal.javac package to jdk.neshkeev in
>>> module-info.java of java.base
>>> 5. `make images` the jdk's source code
>>> 6. I created Main.java with the following content
>>> class Main {
>>>   {
>>>     new jdk.neshkeev.MyPreviewClass();
>>>   }
>>> }
>>> 7. I compiled Main.java with my openjdk that was built in the step 5.
>>> Here is the link to my openjdk fork with the jdk.neshkeev module:
>>> https://github.com/neshkeev/jdk <https://github.com/neshkeev/jdk>
>>> What is expected
>>> Since MyPreviewClass is inside of the package that is annotated with
>>> PreviewFeature and it is also inside of the module that is also
>>> annotated with PreviewFeature I expect to get compile time
>>> errors/warnings. I believe that compile-time errors/warnings should
>>> arise since Main.java can't be considered as participating source code
>>> What happened
>>> No compile-time errors/warnings occurred
>>> Is this a bug?
Reply | Threaded
Open this post in threaded view
|

Re: PreviewFeature on packages and modules

Jonathan Gibbons

On 2/3/21 2:58 PM, Alex Buckley wrote:

> On 2/3/2021 1:30 PM, Jan Lahoda wrote:
>> One thing to note here is e.g. @Deprecated on a package does not
>> automatically deprecate the classes belonging to the given package.
>> Here, we have a package annotated with @PreviewFeature, but not a
>> class annotated as a preview feature, and the preview flag is not
>> propagated from packages to classes, similarly to the deprecated
>> flag. But we can surely make this particular flag to propagate to the
>> classes in the package, if desired.
>
> Thanks for the info. I agree that a package being annotated with
> @PreviewFeature is misleading, since like package deprecation, it's a
> no-op. However, a module being annotated with @PreviewFeature ought to
> have a visible effect if another module `requires` it. If Nikita puts
> Main.java in a module that `requires jdk.neshkeev`, then I'd expect a
> warning/error.
>
> This thread is really about whether explicitly designating a module as
> a preview API implicitly designates every class within the module as a
> preview API. JEP 12 doesn't directly answer that question. It only
> says that every class within the preview module is "participating",
> and what happens if a class _explicitly_ designated as preview is used
> by other code.
>
> The other way of asking the question is: Should a preview module be
> able to contain non-preview classes? (Where every preview class in the
> module would be marked with @PreviewFeature, and any class not so
> marked would be non-preview.)  First issue: you could "silently" use
> such non-preview classes from code on the classpath without a
> `requires` clause to trigger a warning/error for use of the preview
> module itself. This "silent" use feels undesirable, given the preview
> module's non-final status.  Second issue: preview classes and
> non-preview classes could live in the same package (since preview
> classes aren't forced into a dedicated namespace like incubating
> classes) -- that's legitimate when a few preview classes are added to
> a classic package in java.base, but we didn't really envisage a
> handful of non-preview classes hanging out in a vast crowd of preview
> classes in a preview module.
>
> In sum, there's a strong case for saying that everything in a preview
> module has preview status. (Where marking anything in the module with
> @PreviewFeature is legal but redundant.) This would be convenient for
> preview API designers, who could write @PreviewFeature once and have
> it trickle down.
>
> I suspect this is either very painful to implement in javac/javadoc,
> or very easy. Jan, please tell us which! :-)


I would expect this to be almost-zero cost in javadoc, since javadoc
leverages javac.  For javac, I'll leave Jan to give the definitive
answer, but I would expect it to be easy since every class knows its
enclosing package and module.

-- Jon


>
> Alex
>
>>> On 2/3/2021 8:00 AM, Nikita Eshkeev wrote:
>>>> The PreviewFeature
>>>> (https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java 
>>>> <https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java>)
>>>> annotation can be applied to modules and packages. But I don't get
>>>> any compile-time errors/warnings when I try to use code that is
>>>> inside of either a package or a module that is annotated with
>>>> PreviewFeature.
>>>> What I did
>>>> 1. I added a new module to openjdk with the "jdk.neshkeev" name
>>>> 2. I added module-info.java, package-info.java and
>>>> MyPreviewClass.java (which is just an empty class)
>>>> 3. I annotated both module-info.java and package-info.java with
>>>> PreviewFeature
>>>> 4. I exported jdk.internal.javac package to jdk.neshkeev in
>>>> module-info.java of java.base
>>>> 5. `make images` the jdk's source code
>>>> 6. I created Main.java with the following content
>>>> class Main {
>>>>   {
>>>>     new jdk.neshkeev.MyPreviewClass();
>>>>   }
>>>> }
>>>> 7. I compiled Main.java with my openjdk that was built in the step 5.
>>>> Here is the link to my openjdk fork with the jdk.neshkeev module:
>>>> https://github.com/neshkeev/jdk <https://github.com/neshkeev/jdk>
>>>> What is expected
>>>> Since MyPreviewClass is inside of the package that is annotated
>>>> with PreviewFeature and it is also inside of the module that is
>>>> also annotated with PreviewFeature I expect to get compile time
>>>> errors/warnings. I believe that compile-time errors/warnings should
>>>> arise since Main.java can't be considered as participating source code
>>>> What happened
>>>> No compile-time errors/warnings occurred
>>>> Is this a bug?
Reply | Threaded
Open this post in threaded view
|

Re: PreviewFeature on packages and modules

Jan Lahoda
In reply to this post by Alex Buckley-3
On 03. 02. 21 23:58, Alex Buckley wrote:

> On 2/3/2021 1:30 PM, Jan Lahoda wrote:
>> One thing to note here is e.g. @Deprecated on a package does not
>> automatically deprecate the classes belonging to the given package.
>> Here, we have a package annotated with @PreviewFeature, but not a
>> class annotated as a preview feature, and the preview flag is not
>> propagated from packages to classes, similarly to the deprecated
>> flag. But we can surely make this particular flag to propagate to the
>> classes in the package, if desired.
>
> Thanks for the info. I agree that a package being annotated with
> @PreviewFeature is misleading, since like package deprecation, it's a
> no-op. However, a module being annotated with @PreviewFeature ought to
> have a visible effect if another module `requires` it. If Nikita puts
> Main.java in a module that `requires jdk.neshkeev`, then I'd expect a
> warning/error.
>
> This thread is really about whether explicitly designating a module as
> a preview API implicitly designates every class within the module as a
> preview API. JEP 12 doesn't directly answer that question. It only
> says that every class within the preview module is "participating",
> and what happens if a class _explicitly_ designated as preview is used
> by other code.
>
> The other way of asking the question is: Should a preview module be
> able to contain non-preview classes? (Where every preview class in the
> module would be marked with @PreviewFeature, and any class not so
> marked would be non-preview.)  First issue: you could "silently" use
> such non-preview classes from code on the classpath without a
> `requires` clause to trigger a warning/error for use of the preview
> module itself. This "silent" use feels undesirable, given the preview
> module's non-final status.  Second issue: preview classes and
> non-preview classes could live in the same package (since preview
> classes aren't forced into a dedicated namespace like incubating
> classes) -- that's legitimate when a few preview classes are added to
> a classic package in java.base, but we didn't really envisage a
> handful of non-preview classes hanging out in a vast crowd of preview
> classes in a preview module.
>
> In sum, there's a strong case for saying that everything in a preview
> module has preview status. (Where marking anything in the module with
> @PreviewFeature is legal but redundant.) This would be convenient for
> preview API designers, who could write @PreviewFeature once and have
> it trickle down.
>
> I suspect this is either very painful to implement in javac/javadoc,
> or very easy. Jan, please tell us which! :-)


Propagating the preview flag from module to (top-level, presumably)
classes seems to be fairly easy when compiling against classfiles.
Propagating the flag from packages to classes would be more difficult,
as the preview flag is commonly not read for packages - if we were to
change that, we would need start reading all package-info.class files,
with possible implications on performance.


Jan


>
> Alex
>
>>> On 2/3/2021 8:00 AM, Nikita Eshkeev wrote:
>>>> The PreviewFeature
>>>> (https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java 
>>>> <https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java>)
>>>> annotation can be applied to modules and packages. But I don't get
>>>> any compile-time errors/warnings when I try to use code that is
>>>> inside of either a package or a module that is annotated with
>>>> PreviewFeature.
>>>> What I did
>>>> 1. I added a new module to openjdk with the "jdk.neshkeev" name
>>>> 2. I added module-info.java, package-info.java and
>>>> MyPreviewClass.java (which is just an empty class)
>>>> 3. I annotated both module-info.java and package-info.java with
>>>> PreviewFeature
>>>> 4. I exported jdk.internal.javac package to jdk.neshkeev in
>>>> module-info.java of java.base
>>>> 5. `make images` the jdk's source code
>>>> 6. I created Main.java with the following content
>>>> class Main {
>>>>   {
>>>>     new jdk.neshkeev.MyPreviewClass();
>>>>   }
>>>> }
>>>> 7. I compiled Main.java with my openjdk that was built in the step 5.
>>>> Here is the link to my openjdk fork with the jdk.neshkeev module:
>>>> https://github.com/neshkeev/jdk <https://github.com/neshkeev/jdk>
>>>> What is expected
>>>> Since MyPreviewClass is inside of the package that is annotated
>>>> with PreviewFeature and it is also inside of the module that is
>>>> also annotated with PreviewFeature I expect to get compile time
>>>> errors/warnings. I believe that compile-time errors/warnings should
>>>> arise since Main.java can't be considered as participating source code
>>>> What happened
>>>> No compile-time errors/warnings occurred
>>>> Is this a bug?
Reply | Threaded
Open this post in threaded view
|

Re: PreviewFeature on packages and modules

Alex Buckley-3
On 2/4/2021 8:44 AM, Jan Lahoda wrote:

> On 03. 02. 21 23:58, Alex Buckley wrote:
>> In sum, there's a strong case for saying that everything in a preview
>> module has preview status. (Where marking anything in the module with
>> @PreviewFeature is legal but redundant.) This would be convenient for
>> preview API designers, who could write @PreviewFeature once and have
>> it trickle down.
>>
>> I suspect this is either very painful to implement in javac/javadoc,
>> or very easy. Jan, please tell us which! :-)
>
> Propagating the preview flag from module to (top-level, presumably)
> classes seems to be fairly easy when compiling against classfiles.
> Propagating the flag from packages to classes would be more difficult,
> as the preview flag is commonly not read for packages - if we were to
> change that, we would need start reading all package-info.class files,
> with possible implications on performance.

Thanks Jan (and Jon). Propagating the preview flag from module to
top-level classes is all that's required. I'm happy to cut packages out
of the discussion completely, both for the reason you give and because
package-level annotations were a mistake. (Sharp-eyed readers will
notice that JLS 9.6.4.6 no longer mentions "package" as a program
element that can be deprecated.)  If an API designer wishes to preview a
new package, then every top-level class in the package will need to be
flagged @PreviewFeature. JEP 12 can document all this after implementation.

Alex
Reply | Threaded
Open this post in threaded view
|

Re: PreviewFeature on packages and modules

Nikita Eshkeev
Will JEP lose this part about packages:

> For example, if a package java.io.fast is introduced as a preview API, then all of the code in the package would be "participating" and would not generate errors/warnings when referring to the package's own types.

?


04.02.2021, 20:56, "Alex Buckley" <[hidden email]>:

On 2/4/2021 8:44 AM, Jan Lahoda wrote:

 On 03. 02. 21 23:58, Alex Buckley wrote:
 In sum, there's a strong case for saying that everything in a preview
 module has preview status. (Where marking anything in the module with
 @PreviewFeature is legal but redundant.) This would be convenient for
 preview API designers, who could write @PreviewFeature once and have
 it trickle down.

 I suspect this is either very painful to implement in javac/javadoc,
 or very easy. Jan, please tell us which! :-)
 
 Propagating the preview flag from module to (top-level, presumably)
 classes seems to be fairly easy when compiling against classfiles.
 Propagating the flag from packages to classes would be more difficult,
 as the preview flag is commonly not read for packages - if we were to
 change that, we would need start reading all package-info.class files,
 with possible implications on performance.


Thanks Jan (and Jon). Propagating the preview flag from module to
top-level classes is all that's required. I'm happy to cut packages out
of the discussion completely, both for the reason you give and because
package-level annotations were a mistake. (Sharp-eyed readers will
notice that JLS 9.6.4.6 no longer mentions "package" as a program
element that can be deprecated.) If an API designer wishes to preview a
new package, then every top-level class in the package will need to be
flagged @PreviewFeature. JEP 12 can document all this after implementation.

Alex




Reply | Threaded
Open this post in threaded view
|

Re: PreviewFeature on packages and modules

Alex Buckley-3
In reply to this post by Alex Buckley-3
On 2/4/2021 9:53 AM, Alex Buckley wrote:
> Thanks Jan (and Jon). Propagating the preview flag from module to
> top-level classes is all that's required. I'm happy to cut packages out
> of the discussion completely, both for the reason you give and because
> package-level annotations were a mistake. (Sharp-eyed readers will
> notice that JLS 9.6.4.6 no longer mentions "package" as a program
> element that can be deprecated.)  If an API designer wishes to preview a
> new package, then every top-level class in the package will need to be
> flagged @PreviewFeature. JEP 12 can document all this after implementation.

We should probably switch "top-level classes" to "public classes,
whether top level or nested". The preview module might not export a
package, in which case it doesn't matter that we treat the package's
public classes as preview (since they're inaccessible); but if the
preview module does export a package, then we should recognize its
public nested classes as part of the API alongside its public top level
classes (consider j.l.i.MethodHandles.Lookup).

Alex
Reply | Threaded
Open this post in threaded view
|

Re: [External] : Re: PreviewFeature on packages and modules

Alex Buckley-3
In reply to this post by Nikita Eshkeev
That text would be corrected to clarify that adding a package
java.io.fast as a preview API in java.base (a perfectly good concept)
means the API designer has to flag classes in the package as preview
APIs (due to how @PreviewFeature is interpreted); and that _all_ classes
in the package (top level or nested; public or private) are
"participating". A private nested helper class should obviously be able
to refer to the in-preview public entrypoints of the API without
warning/error.

Alex

On 2/4/2021 12:55 PM, Nikita Eshkeev wrote:

> Will JEP lose this part about packages:
>
>  > For example, if a package java.io.fast is introduced as a preview
> API, then all of the code in the package would be "participating" and
> would not generate errors/warnings when referring to the package's own
> types.
>
> ?
>
>
> 04.02.2021, 20:56, "Alex Buckley" <[hidden email]>:
>
>     On 2/4/2021 8:44 AM, Jan Lahoda wrote:
>
>           On 03. 02. 21 23:58, Alex Buckley wrote:
>
>               In sum, there's a strong case for saying that everything
>             in a preview
>               module has preview status. (Where marking anything in the
>             module with
>               @PreviewFeature is legal but redundant.) This would be
>             convenient for
>               preview API designers, who could write @PreviewFeature
>             once and have
>               it trickle down.
>
>               I suspect this is either very painful to implement in
>             javac/javadoc,
>               or very easy. Jan, please tell us which! :-)
>
>
>           Propagating the preview flag from module to (top-level,
>         presumably)
>           classes seems to be fairly easy when compiling against
>         classfiles.
>           Propagating the flag from packages to classes would be more
>         difficult,
>           as the preview flag is commonly not read for packages - if we
>         were to
>           change that, we would need start reading all
>         package-info.class files,
>           with possible implications on performance.
>
>
>     Thanks Jan (and Jon). Propagating the preview flag from module to
>     top-level classes is all that's required. I'm happy to cut packages out
>     of the discussion completely, both for the reason you give and because
>     package-level annotations were a mistake. (Sharp-eyed readers will
>     notice that JLS 9.6.4.6 no longer mentions "package" as a program
>     element that can be deprecated.) If an API designer wishes to preview a
>     new package, then every top-level class in the package will need to be
>     flagged @PreviewFeature. JEP 12 can document all this after
>     implementation.
>
>     Alex
>
>
>
>
Reply | Threaded
Open this post in threaded view
|

Re: PreviewFeature on packages and modules

Jan Lahoda
In reply to this post by Alex Buckley-3
On 04. 02. 21 22:47, Alex Buckley wrote:

> On 2/4/2021 9:53 AM, Alex Buckley wrote:
>> Thanks Jan (and Jon). Propagating the preview flag from module to
>> top-level classes is all that's required. I'm happy to cut packages
>> out of the discussion completely, both for the reason you give and
>> because package-level annotations were a mistake. (Sharp-eyed readers
>> will notice that JLS 9.6.4.6 no longer mentions "package" as a
>> program element that can be deprecated.)  If an API designer wishes
>> to preview a new package, then every top-level class in the package
>> will need to be flagged @PreviewFeature. JEP 12 can document all this
>> after implementation.
>
> We should probably switch "top-level classes" to "public classes,
> whether top level or nested". The preview module might not export a
> package, in which case it doesn't matter that we treat the package's
> public classes as preview (since they're inaccessible); but if the
> preview module does export a package, then we should recognize its
> public nested classes as part of the API alongside its public top
> level classes (consider j.l.i.MethodHandles.Lookup).


I'd point out it is not easy to refer to a nested class without first
referring to the enclosing class (could happen e.g. when the code can
refer to the nested class using simple name e.g. due to inheritance).
And showing warnings on both the enclosing and nested class may be
discouraging.


But there is a possibly bigger question: if we copy the flags from
modules to nested classes, should we copy them from preview classes (in
non-preview modules) to their nested classes? Or from preview classes to
their members and constructors? (This is very unlike e.g. deprecation,
which does not copy the flag to any enclosed element, AFAIK.)


Jan


>
> Alex
Reply | Threaded
Open this post in threaded view
|

Re: PreviewFeature on packages and modules

Alex Buckley-3
On 2/5/2021 2:55 AM, Jan Lahoda wrote:

>> On 2/4/2021 9:53 AM, Alex Buckley wrote:
>> We should probably switch "top-level classes" to "public classes,
>> whether top level or nested". The preview module might not export a
>> package, in which case it doesn't matter that we treat the package's
>> public classes as preview (since they're inaccessible); but if the
>> preview module does export a package, then we should recognize its
>> public nested classes as part of the API alongside its public top
>> level classes (consider j.l.i.MethodHandles.Lookup).
>
> I'd point out it is not easy to refer to a nested class without first
> referring to the enclosing class (could happen e.g. when the code can
> refer to the nested class using simple name e.g. due to inheritance).

I'm completely with you. My concern is that if JEP 12 focuses on
[public] _top level_ classes in [an exported package of] a preview
module, then Nikita will be along two minutes later to ask if [public]
nested classes inside those top level classes are preview APIs too. The
answer is "yes", so in some sense the [public] nested classes should be
treated as having @PreviewFeature too. (Please don't respond yet. Please
keep reading.)

> And showing warnings on both the enclosing and nested class may be
> discouraging.

Again, you're right, and javac as a quality-of-implementation matter
could choose to give only a warning for the enclosing class name.

> But there is a possibly bigger question: if we copy the flags from
> modules to nested classes, should we copy them from preview classes (in
> non-preview modules) to their nested classes? Or from preview classes to
> their members and constructors? (This is very unlike e.g. deprecation,
> which does not copy the flag to any enclosed element, AFAIK.)

Yes, we were heading for this question regardless of Nikita's question
about packages and modules. Conceptually, putting @PreviewFeature on a
top level class means that all of its public members and ctors are a
preview API. Practically, I agree with your earlier comment that it's
hard to use a member without using the enclosing class name. So, while
JEP 12 will clarify that a preview module causes all its accessible
public classes (top level or nested) to be in preview, I think javac
need only copy preview status from module to top level classes in order
to tell clients what they're using.

Alex
Reply | Threaded
Open this post in threaded view
|

Re: PreviewFeature on packages and modules

Nikita Eshkeev
- все
 
Here is a summary of what's been discussed in this thread:
 
1. If a module is annotated with PreviewFeature (in module-info.java) then the preview feature flag gets to be propagated to all the classes (top level or not) in the module and they are considered a PreviewFeature too;
2. If a package is annotated with PreviewFeature (in package-info.java) then the preview feature flag doesn't get to be propagated to the classes in the package;
3. If a class is annotated with PreviewFeature then all the inner classes (regardless if they are static or not) are also considered a PreviewFeature;
4. If a class or a class member is annotated with PreviewFeature and it is used in a different class in the same package then no compile-time errors/warnings occur, because the latter class is considered as participating source code.
5. If a class is annotated with PreviewFeature then all its members (regardless if they are static or not) are considered a PreviewFeature too
 
Additional questions:
1. If a module is annotated with PreviewFeature then javac raises a compile-time errors/warnings when it's used in a requires statement of another module. Is this true?
2. If a module is not annotated with PreviewFeature then each export statement of a package that is annotated with PreviewFeaturein in module-info.java should lead to compile-time errors/warnings. Is this true?
3. If a module is not annotated with PreviewFeature then each provides statement of a class that is annotated with PreviewFeature in module-info.java should lead to compile-time errors/warnings. Is this true?
4. If a class inherits/implements a class/interface that is marked as PreviewFeature then the class is considered a PreviewFeature. Is this true?
 
 
 
05.02.2021, 23:57, "Alex Buckley" <[hidden email]>:

On 2/5/2021 2:55 AM, Jan Lahoda wrote:

 On 2/4/2021 9:53 AM, Alex Buckley wrote:
 We should probably switch "top-level classes" to "public classes,
 whether top level or nested". The preview module might not export a
 package, in which case it doesn't matter that we treat the package's
 public classes as preview (since they're inaccessible); but if the
 preview module does export a package, then we should recognize its
 public nested classes as part of the API alongside its public top
 level classes (consider j.l.i.MethodHandles.Lookup).
 
 I'd point out it is not easy to refer to a nested class without first
 referring to the enclosing class (could happen e.g. when the code can
 refer to the nested class using simple name e.g. due to inheritance).


I'm completely with you. My concern is that if JEP 12 focuses on
[public] _top level_ classes in [an exported package of] a preview
module, then Nikita will be along two minutes later to ask if [public]
nested classes inside those top level classes are preview APIs too. The
answer is "yes", so in some sense the [public] nested classes should be
treated as having @PreviewFeature too. (Please don't respond yet. Please
keep reading.)
 

 And showing warnings on both the enclosing and nested class may be
 discouraging.


Again, you're right, and javac as a quality-of-implementation matter
could choose to give only a warning for the enclosing class name.
 

 But there is a possibly bigger question: if we copy the flags from
 modules to nested classes, should we copy them from preview classes (in
 non-preview modules) to their nested classes? Or from preview classes to
 their members and constructors? (This is very unlike e.g. deprecation,
 which does not copy the flag to any enclosed element, AFAIK.)


Yes, we were heading for this question regardless of Nikita's question
about packages and modules. Conceptually, putting @PreviewFeature on a
top level class means that all of its public members and ctors are a
preview API. Practically, I agree with your earlier comment that it's
hard to use a member without using the enclosing class name. So, while
JEP 12 will clarify that a preview module causes all its accessible
public classes (top level or nested) to be in preview, I think javac
need only copy preview status from module to top level classes in order
to tell clients what they're using.

Alex

Reply | Threaded
Open this post in threaded view
|

Re: PreviewFeature on packages and modules

Alex Buckley-3
On 2/8/2021 8:00 AM, Nikita Eshkeev wrote:
> Additional questions:
> 1. If a module is annotated with PreviewFeature then javac raises a
> compile-time errors/warnings when it's used in a requires statement of
> another module. Is this true?

It should be.

> 2. If a module is not annotated with PreviewFeature then each export
> statement of a package that is annotated with PreviewFeaturein in
> module-info.java should lead to compile-time errors/warnings. Is this true?

Package annotations are a no-op. Don't expect any warnings/errors from
javac if your module `exports` a package annotated @PreviewFeature.

> 3. If a module is not annotated with PreviewFeature then each provides
> statement of a class that is annotated with PreviewFeature in
> module-info.java should lead to compile-time errors/warnings. Is this true?

Yes, that counts as a source code reference to a preview API element.

> 4. If a class inherits/implements a class/interface that is marked as
> PreviewFeature then the class is considered a PreviewFeature. Is this true?

No, that's an over-reading of JEP 12. Assuming that the
inheriting/implementing class C is not "participating" for the preview
class P, C's `extends`/`implements` clause will generate a warning/error
and C.class will be marked as depending on preview features, just as if
C had declared a field of type P or C's code had used a preview language
feature. The javadoc for C will display that C's
superclass/superinterface is a preview API.

Alex