On Tue, 21 Apr 2026 13:24:29 GMT, Severin Gehwolf <[email protected]> wrote:
>>> This was discussed quite a lot initially in the design phase, and I
>>> personally think what we have is the better choice.
>>
>> This choice means 3 different views of the resources:
>> 1. resources in META-INF/preview are hidden when preview features are
>> disabled
>> 2. resources in META-INF/preview are overlaid when preview features are
>> enabled
>> 3. the "raw" view where resources in META-INF/preview are just resources in
>> the module (the existing world)
>>
>> There is a lot of complexity in this, which is partly why it has taken me a
>> long time to go through all these changes. This is why I'm wondering about
>> making this simpler so that there are only 2 views.
>>
>>> Having any user code care or know what is in preview mode today is
>>> inherently unstable in ways that knowing what was in version 3.7 of a
>>> library isn't.
>>
>> If you mean that user code might test for resources in META-INF/preview to
>> know if the VM has preview features enabled then there are many other ways
>> to infer this. But maybe you mean something else?
>
>> There is a lot of complexity in this, which is partly why it has taken me a
>> long time to go through all these changes. This is why I'm wondering about
>> making this simpler so that there are only 2 views.
>
> I for one, would welcome only two views. For my taste there are some strange
> inconsistencies (I'm using valhalla EA JDK for this):
>
> $ ./bin/jshell
> | Welcome to JShell -- Version 27-jep401ea3
> | For an introduction type: /help intro
>
> jshell> var mref = ModuleFinder.ofSystem().find("java.base").orElseThrow();
> mref ==> [module java.base, location=jrt:/java.base]
>
> jshell> var bytePreviewResource = "META-INF/preview/java/lang/Byte.class";
> bytePreviewResource ==> "META-INF/preview/java/lang/Byte.class"
>
> jshell> var bytePreview = mref.open().list().filter(n ->
> n.equals(bytePreviewResource)).toList();
> bytePreview ==> []
>
> jshell> var inStream = mref.open().find(bytePreviewResource).orElseThrow();
> inStream ==> jrt:/java.base/META-INF/preview/java/lang/Byte.class
>
>
> i.e. the `bytePreview` variable would not be empty when an InputStream for
> the same resource can be found (using `ModuleReader.find()`).
>
> Also the `open()` call returns the resource's inputstream:
>
>
> bin/jshell
> | Welcome to JShell -- Version 27-jep401ea3
> | For an introduction type: /help intro
>
> jshell> var bytePreviewResource = "META-INF/preview/java/lang/Byte.class";
> bytePreviewResource ==> "META-INF/preview/java/lang/Byte.class"
>
> jshell> var inStream =
> java.lang.Object.class.getResourceAsStream(bytePreviewResource);
> inStream ==> null
>
> jshell> var inStream = java.lang.Object.class.getResourceAsStream("/" +
> bytePreviewResource);
> inStream ==> java.io.ByteArrayInputStream@67205a84
>
> jshell> var mref = ModuleFinder.ofSystem().find("java.base").orElseThrow();
> mref ==> [module java.base, location=jrt:/java.base]
>
> jshell> var inStream = mref.open().open(bytePreviewResource).orElseThrow();
> inStream ==> java.io.ByteArrayInputStream@5e853265
>
> jshell>
I'm not seeing the same behaviour with jshell. And what I'm seeing is exactly
what I expect to see.
[jdk/beta/open -> jimage_preview_mode]%
../build/linux-x64/images/jdk/bin/jshell
| Welcome to JShell -- Version 27-internal
| For an introduction type: /help intro
jshell> var mref = ModuleFinder.ofSystem().find("java.base").orElseThrow();
mref ==> [module java.base, location=jrt:/java.base]
jshell> var bytePreviewResource = "META-INF/preview/java/lang/Byte.class";
bytePreviewResource ==> "META-INF/preview/java/lang/Byte.class"
jshell> var bytePreview = mref.open().list().filter(n ->
n.equals(bytePreviewResource)).toList();
bytePreview ==> []
jshell> var inStream = mref.open().find(bytePreviewResource).orElseThrow();
| Exception java.util.NoSuchElementException: No value present
| at Optional.orElseThrow (Optional.java:381)
| at do_it$Aux (#4:1)
| at (#4:1)
jshell> var inStream =
java.lang.Object.class.getResourceAsStream(bytePreviewResource);
inStream ==> null
jshell> var inStream = java.lang.Object.class.getResourceAsStream("/" +
bytePreviewResource);
inStream ==> null
jshell> var mref = ModuleFinder.ofSystem().find("java.base").orElseThrow();
mref ==> [module java.base, location=jrt:/java.base]
jshell> var inStream = mref.open().open(bytePreviewResource).orElseThrow();
| Exception java.util.NoSuchElementException: No value present
| at Optional.orElseThrow (Optional.java:381)
| at do_it$Aux (#8:1)
| at (#8:1)
(that's with this PR patched into head as it would be submitted now).
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/29414#discussion_r3122904880