From mark.reinhold at oracle.com Mon Oct 21 16:14:19 2024 From: mark.reinhold at oracle.com (Mark Reinhold) Date: Mon, 21 Oct 2024 16:14:19 +0000 Subject: New candidate JEP: 493: Linking Run-Time Images without JMODs Message-ID: <20241021161418.0CD9677ED45@eggemoggin.niobe.net> https://openjdk.org/jeps/493 Summary: Reduce the size of the JDK by approximately 25% by enabling the jlink tool to create custom run-time images without using the JDK's JMOD files. This feature must be enabled when the JDK is built; it will not be enabled by default, and some JDK vendors may choose not to enable it. - Mark From alex.buckley at oracle.com Mon Oct 21 18:19:47 2024 From: alex.buckley at oracle.com (Alex Buckley) Date: Mon, 21 Oct 2024 11:19:47 -0700 Subject: New candidate JEP: 493: Linking Run-Time Images without JMODs In-Reply-To: <20241021161418.0CD9677ED45@eggemoggin.niobe.net> References: <20241021161418.0CD9677ED45@eggemoggin.niobe.net> Message-ID: <804b385a-2532-4b0d-8f26-edd4278bd3f7@oracle.com> On 10/21/2024 9:14 AM, Mark Reinhold wrote: > https://openjdk.org/jeps/493 I was surprised to learn that the jlink tool which can link from a run-time image is only available in a JDK built with --enable-linkable-runtime. As a user, can I tell if the jlink tool in my installed JDK consumes JMODs or consumes run-time images? I am also not crystal clear whether jlink in a JDK built with --enable-linkable-runtime is capable of consuming run-time images _and_ JMODs, or just run-time images. If it can consume run-time images _and_ JMODs, which origin is preferred when resolving modules passed to --add-modules? Can it consume only the run-time image it was built as a part of, or can I point --module-path to other run-time images? (presumably built with --enable-linkable-runtime themselves) It would be good if the JEP could clarify these points for all readers. As an editorial note, this text can't be true: "The jlink tool in the resulting JDK works exactly the same way as the jlink tool in a JDK built with the default configuration." -- the jlink tool in the resulting JDK will extract from the run-time image, not from JMOD files, so it's not working "exactly the same way". I think you mean that _running_ the jlink tool in the resulting JDK is done in exactly the same way. Alex From alan.bateman at oracle.com Tue Oct 22 09:03:07 2024 From: alan.bateman at oracle.com (Alan Bateman) Date: Tue, 22 Oct 2024 10:03:07 +0100 Subject: New candidate JEP: 493: Linking Run-Time Images without JMODs In-Reply-To: <804b385a-2532-4b0d-8f26-edd4278bd3f7@oracle.com> References: <20241021161418.0CD9677ED45@eggemoggin.niobe.net> <804b385a-2532-4b0d-8f26-edd4278bd3f7@oracle.com> Message-ID: On 21/10/2024 19:19, Alex Buckley wrote: > On 10/21/2024 9:14 AM, Mark Reinhold wrote: >> https://openjdk.org/jeps/493 > > I was surprised to learn that the jlink tool which can link from a > run-time image is only available in a JDK built with > --enable-linkable-runtime. As a user, can I tell if the jlink tool in > my installed JDK consumes JMODs or consumes run-time images? > > I am also not crystal clear whether jlink in a JDK built with > --enable-linkable-runtime is capable of consuming run-time images > _and_ JMODs, or just run-time images. > > If it can consume run-time images _and_ JMODs, which origin is > preferred when resolving modules passed to --add-modules? > > Can it consume only the run-time image it was built as a part of, or > can I point --module-path to other run-time images? (presumably built > with --enable-linkable-runtime themselves) > > It would be good if the JEP could clarify these points for all readers. > > As an editorial note, this text can't be true: "The jlink tool in the > resulting JDK works exactly the same way as the jlink tool in a JDK > built with the default configuration." -- the jlink tool in the > resulting JDK will extract from the run-time image, not from JMOD > files, so it's not working "exactly the same way". I think you mean > that _running_ the jlink tool in the resulting JDK is done in exactly > the same way. As a user, the JDK you download may contain a "jmods" directory, it may not. This should just work: ??? $JDK/bin/jlink --add-modules java.se --output myjdk It doesn't matter if jlink uses packaged modules in $JDK/jmods or reconstitutes the module content from $JDK run-time image by other means. That was the intention of the example and "The jlink tool in the resulting JDK works exactly .." in the Description. Every jlink in every JDK build can consume JMOD files. I'm trying to see if there is anything in the JEP that suggests otherwise. I don't expect most developers will come across JMOD files, except developers using JavaFX where a command line this will just work: ?? jlink --module-path javafx-mods --add-modules javafx.graphics,javafx.web,java.se --output myjdk The JavaFX modules (in JMOD format) will be found in javafx-mods. The java.* modules will comes from the JDK. jlink support for using the packaged modules in another JDK is very limited. You can do this today: ? $JDK1/bin/jlink --module-path $JDK2/jmods --add-modules java.se --output myjdk but only if $JDK1 and $JDK2 are the same version, otherwise you get an error like "Error: jlink version 24.0 does not match target java.base version 22.0". The motive for this is cross-linking where you run jlink on one platform to produce the run-time images that you need for all platforms. The JEP doesn't change anything in this area. This cross linking needs packaged modules so can't point to the jmods directory of a JDK built with --enable-linkable-runtime as there is no jmods directory. This is the "Cross-linking" item in the Restrictions section but it might be that this term is not widely known so the implications of item 3 may not be clear. -Alan From sgehwolf at redhat.com Tue Oct 22 09:17:27 2024 From: sgehwolf at redhat.com (Severin Gehwolf) Date: Tue, 22 Oct 2024 11:17:27 +0200 Subject: New candidate JEP: 493: Linking Run-Time Images without JMODs In-Reply-To: <804b385a-2532-4b0d-8f26-edd4278bd3f7@oracle.com> References: <20241021161418.0CD9677ED45@eggemoggin.niobe.net> <804b385a-2532-4b0d-8f26-edd4278bd3f7@oracle.com> Message-ID: <8ff5260046e28c67c8d17ea5cc172e1fae8eccd4.camel@redhat.com> Hi Alex, Thanks for your input! On Mon, 2024-10-21 at 11:19 -0700, Alex Buckley wrote: > On 10/21/2024 9:14 AM, Mark Reinhold wrote: > > https://openjdk.org/jeps/493 > > I was surprised to learn that the jlink tool which can link from a > run-time image is only available in a JDK built with > --enable-linkable-runtime. As a user, can I tell if the jlink tool in my > installed JDK consumes JMODs or consumes run-time images? Yes. Using --verbose will show this for a run-time image link: """ $ ./runtime-image-link-jdk/bin/jlink --add-modules java.base \ --output ./java.base-from-run-time --verbose Linking based on the current run-time image. java.base jrt:/java.base (run-time image) Providers: java.base provides java.nio.file.spi.FileSystemProvider used by java.base """ Conversely, if JMODs are present - for a build with --enable-linkable-runtime - the verbose output looks as before: """ $ ./jdk/bin/jlink --add-modules java.base \ --output ./java.base-from-jmods --verbose java.base file:///path/to/jdk/jmods/java.base.jmod Providers: java.base provides java.nio.file.spi.FileSystemProvider used by java.base """ I.e. it tells the user where it is taking the bits from (JMODs or run- time image). An earlier incarnation of the JEP did have this output always enabled when performing a link from the run-time image: $ jlink --add-modules java.xml --output myimage Linking based on the current run-time image. Based on previous feedback, we chose not to print this to stdout by default since that might break some users who parse jlink output. I'm happy to expand the JEP with this detail, but this would be for expert users and not exactly the intended target audience of JEP readers. It's not clear if it'll confuse readers of the JEP or provides clarity. The associated CSR will have those details. > I am also not crystal clear whether jlink in a JDK built with > --enable-linkable-runtime is capable of consuming run-time images _and_ > JMODs, or just run-time images. Both. As answered before, if the java.base module is specified on the module path (or the default module path has JMODs - `$JDK/jmods`) then it will try to use the java.base.jmod from there. Again, --verbose will show this distinction. Only if none of the other options are available it will link from the run-time image. > If it can consume run-time images _and_ JMODs, which origin is preferred > when resolving modules passed to --add-modules? JMODs are preferred. > Can it consume only the run-time image it was built as a part of, or can > I point --module-path to other run-time images? (presumably built with > --enable-linkable-runtime themselves) Right now, only the run-time image it was built as a part of. > It would be good if the JEP could clarify these points for all readers. OK, thanks. I'll confer with previous reviewers and will work on an update to clarify this. > As an editorial note, this text can't be true: "The jlink tool in the > resulting JDK works exactly the same way as the jlink tool in a JDK > built with the default configuration." -- the jlink tool in the > resulting JDK will extract from the run-time image, not from JMOD files, > so it's not working "exactly the same way". I think you mean that > _running_ the jlink tool in the resulting JDK is done in exactly the > same way. Makes sense. How about this? """ Invoking the jlink tool in the resulting JDK works exactly the same way as the jlink tool in a JDK built with the default configuration. """ Thanks, Severin From alex.buckley at oracle.com Tue Oct 22 17:10:05 2024 From: alex.buckley at oracle.com (Alex Buckley) Date: Tue, 22 Oct 2024 10:10:05 -0700 Subject: [External] : Re: New candidate JEP: 493: Linking Run-Time Images without JMODs In-Reply-To: <8ff5260046e28c67c8d17ea5cc172e1fae8eccd4.camel@redhat.com> References: <20241021161418.0CD9677ED45@eggemoggin.niobe.net> <804b385a-2532-4b0d-8f26-edd4278bd3f7@oracle.com> <8ff5260046e28c67c8d17ea5cc172e1fae8eccd4.camel@redhat.com> Message-ID: <05f2f0c6-1c7c-4ff8-b0e8-c3cb2a8ca9a2@oracle.com> On 10/22/2024 2:17 AM, Severin Gehwolf wrote: > Using --verbose will show this for a run-time image link: > > """ > $ ./runtime-image-link-jdk/bin/jlink --add-modules java.base \ > --output ./java.base-from-run-time --verbose > Linking based on the current run-time image. > java.base jrt:/java.base (run-time image) ... > Conversely, if JMODs are present - for a build with > --enable-linkable-runtime - the verbose output looks as before: > > """ > $ ./jdk/bin/jlink --add-modules java.base \ > --output ./java.base-from-jmods --verbose > java.base file:///path/to/jdk/jmods/java.base.jmod ... > I.e. it tells the user where it is taking the bits from (JMODs or run- > time image). > > I'm happy to expand the JEP with this detail, but this would be for > expert users and not exactly the intended target audience of JEP > readers. It's not clear if it'll confuse readers of the JEP or provides > clarity. In no way is this a "detail" for expert users. If I have a JDK on my machine, perhaps provided by my employer or my school, I want to be able to find out if the jlink in that JDK can link from just JMODs or from <>. It's a basic question about the functionality of the jlink on my machine. It seems that I can't get the answer by simply running `jlink --help` -- I have to actually do some linking. It would be helpful if the JEP said this plainly in the Description. >> I am also not crystal clear whether jlink in a JDK built with >> --enable-linkable-runtime is capable of consuming run-time images _and_ >> JMODs, or just run-time images. > > Both. As answered before, if the java.base module is specified on the > module path (or the default module path has JMODs - `$JDK/jmods`) then > it will try to use the java.base.jmod from there. Again, --verbose will > show this distinction. Only if none of the other options are available > it will link from the run-time image. The JEP needs to explain this JMODs-win policy: "A version of jlink that can consume both JMODs and run-time images always prefers to consume a module from a JMOD on the module path if available. Only if such a module is not found does jlink consume the module from the run-time image of which jlink is part." >> As an editorial note, this text can't be true: "The jlink tool in the >> resulting JDK works exactly the same way as the jlink tool in a JDK >> built with the default configuration." -- the jlink tool in the >> resulting JDK will extract from the run-time image, not from JMOD files, >> so it's not working "exactly the same way". I think you mean that >> _running_ the jlink tool in the resulting JDK is done in exactly the >> same way. > > Makes sense. How about this? > > """ > Invoking the jlink tool in the resulting JDK works exactly the same way > as the jlink tool in a JDK built with the default configuration. > """ This still suggests that the _effect_ of invoking jlink in the resulting JDK is the same ("works exactly the same way") as invoking jlink in the default configuration. In fact, the effect is different. The thing that is the same is the _user experience_ -- what operands they give to jlink on the command line. Alex From alex.buckley at oracle.com Tue Oct 22 17:28:58 2024 From: alex.buckley at oracle.com (Alex Buckley) Date: Tue, 22 Oct 2024 10:28:58 -0700 Subject: New candidate JEP: 493: Linking Run-Time Images without JMODs In-Reply-To: References: <20241021161418.0CD9677ED45@eggemoggin.niobe.net> <804b385a-2532-4b0d-8f26-edd4278bd3f7@oracle.com> Message-ID: On 10/22/2024 2:03 AM, Alan Bateman wrote: > As a user, the JDK you download may contain a "jmods" directory, it may > not. This should just work: > > ??? $JDK/bin/jlink --add-modules java.se --output myjdk > > It doesn't matter if jlink uses packaged modules in $JDK/jmods or > reconstitutes the module content from $JDK run-time image by other > means. There is no Goal that communicates: "Allow users to link a run-time image from modules on their machine without regard for whether those modules exist as standalone JMOD files or exist in a run-time image linked previously." > Every jlink in every JDK build can consume JMOD files. It would be helpful to state this. And then: "In addition, in some JDK installations, jlink can consume modules from the run-time image of which it is part. Whether jlink can do this depends on how its run-time image was built." > jlink support for using the packaged modules in another JDK is very > limited. You can do this today: > > ? $JDK1/bin/jlink --module-path $JDK2/jmods --add-modules java.se -- > output myjdk > > but only if $JDK1 and $JDK2 are the same version, otherwise you get an > error like "Error: jlink version 24.0 does not match target java.base > version 22.0". I might have a variety of run-time images installed on my (say) Windows machine, so it would be convenient if I could consume modules from one or more of those images when building a new run-time image -- I wouldn't need to ask anyone for JMOD files. This scenario is completely unrelated to cross-platform linking. I see now that this scenario is not supported because I can't point --module-path to another run-time image, only to a location of JMODs. It would be helpful if the JEP stated this plainly, rather than expecting readers to know everything about jlink and then apply an "Unchanged unless we say otherwise" filter. Alex From sgehwolf at redhat.com Tue Oct 22 19:03:41 2024 From: sgehwolf at redhat.com (Severin Gehwolf) Date: Tue, 22 Oct 2024 21:03:41 +0200 Subject: [External] : Re: New candidate JEP: 493: Linking Run-Time Images without JMODs In-Reply-To: <05f2f0c6-1c7c-4ff8-b0e8-c3cb2a8ca9a2@oracle.com> References: <20241021161418.0CD9677ED45@eggemoggin.niobe.net> <804b385a-2532-4b0d-8f26-edd4278bd3f7@oracle.com> <8ff5260046e28c67c8d17ea5cc172e1fae8eccd4.camel@redhat.com> <05f2f0c6-1c7c-4ff8-b0e8-c3cb2a8ca9a2@oracle.com> Message-ID: <2b8b76c27bd7ad841bf1f806903cdfe6034a2751.camel@redhat.com> On Tue, 2024-10-22 at 10:10 -0700, Alex Buckley wrote: > On 10/22/2024 2:17 AM, Severin Gehwolf wrote: > > Using --verbose will show this for a run-time image link: > > > > """ > > ???? $ ./runtime-image-link-jdk/bin/jlink --add-modules java.base \ > > ???????????????? --output ./java.base-from-run-time --verbose > > ???? Linking based on the current run-time image. > > ???? java.base jrt:/java.base (run-time image) > ... > > Conversely, if JMODs are present - for a build with > > --enable-linkable-runtime - the verbose output looks as before: > > > > """ > > ???? $ ./jdk/bin/jlink --add-modules java.base \ > > ???????????????? --output ./java.base-from-jmods --verbose > > ???? java.base file:///path/to/jdk/jmods/java.base.jmod > ... > > I.e. it tells the user where it is taking the bits from (JMODs or run- > > time image). > > > > I'm happy to expand the JEP with this detail, but this would be for > > expert users and not exactly the intended target audience of JEP > > readers. It's not clear if it'll confuse readers of the JEP or provides > > clarity. > > In no way is this a "detail" for expert users. If I have a JDK on my > machine, perhaps provided by my employer or my school, I want to be able > to find out if the jlink in that JDK can link from just JMODs or from > <>. It's a basic question about the > functionality of the jlink on my machine. It seems that I can't get the > answer by simply running `jlink --help` It's a good point. I believe `jlink --help` having this reporting would be a nice addition. > I have to actually do some > linking. It would be helpful if the JEP said this plainly in the > Description. Makes sense. > > > I am also not crystal clear whether jlink in a JDK built with > > > --enable-linkable-runtime is capable of consuming run-time images _and_ > > > JMODs, or just run-time images. > > > > Both. As answered before, if the java.base module is specified on the > > module path (or the default module path has JMODs - `$JDK/jmods`) then > > it will try to use the java.base.jmod from there. Again, --verbose will > > show this distinction. Only if none of the other options are available > > it will link from the run-time image. > > The JEP needs to explain this JMODs-win policy:? "A version of jlink > that can consume both JMODs and run-time images always prefers to > consume a module from a JMOD on the module path if available. Only if > such a module is not found does jlink consume the module from the > run-time image of which jlink is part." I'll add it. > > > As an editorial note, this text can't be true: "The jlink tool in the > > > resulting JDK works exactly the same way as the jlink tool in a JDK > > > built with the default configuration." -- the jlink tool in the > > > resulting JDK will extract from the run-time image, not from JMOD files, > > > so it's not working "exactly the same way". I think you mean that > > > _running_ the jlink tool in the resulting JDK is done in exactly the > > > same way. > > > > Makes sense. How about this? > > > > """ > > Invoking the jlink tool in the resulting JDK works exactly the same way > > as the jlink tool in a JDK built with the default configuration. > > """ > > This still suggests that the _effect_ of invoking jlink in the resulting > JDK is the same ("works exactly the same way") as invoking jlink in the > default configuration. In fact, the effect is different. The thing that > is the same is the _user experience_ -- what operands they give to jlink > on the command line. OK. Thanks, Severin From sgehwolf at redhat.com Tue Oct 22 19:09:59 2024 From: sgehwolf at redhat.com (Severin Gehwolf) Date: Tue, 22 Oct 2024 21:09:59 +0200 Subject: New candidate JEP: 493: Linking Run-Time Images without JMODs In-Reply-To: References: <20241021161418.0CD9677ED45@eggemoggin.niobe.net> <804b385a-2532-4b0d-8f26-edd4278bd3f7@oracle.com> Message-ID: On Tue, 2024-10-22 at 10:28 -0700, Alex Buckley wrote: > > Every jlink in every JDK build can consume JMOD files. > > It would be helpful to state this. And then: "In addition, in some JDK > installations, jlink can consume modules from the run-time image of > which it is part. Whether jlink can do this depends on how its run-time > image was built." OK. > > jlink support for using the packaged modules in another JDK is very > > limited. You can do this today: > > > > ?? $JDK1/bin/jlink --module-path $JDK2/jmods --add-modules java.se -- > > output myjdk > > > > but only if $JDK1 and $JDK2 are the same version, otherwise you get an > > error like "Error: jlink version 24.0 does not match target java.base > > version 22.0". > > I might have a variety of run-time images installed on my (say) Windows > machine, so it would be convenient if I could consume modules from one > or more of those images when building a new run-time image -- I wouldn't > need to ask anyone for JMOD files. This scenario is completely unrelated > to cross-platform linking. > > I see now that this scenario is not supported because I can't point > --module-path to another run-time image, only to a location of JMODs. It > would be helpful if the JEP stated this plainly, rather than expecting > readers to know everything about jlink and then apply an "Unchanged > unless we say otherwise" filter. I will add a clarifying sentence about this. Thanks, Severin From alex.buckley at oracle.com Tue Oct 22 20:54:16 2024 From: alex.buckley at oracle.com (Alex Buckley) Date: Tue, 22 Oct 2024 13:54:16 -0700 Subject: New candidate JEP: 493: Linking Run-Time Images without JMODs In-Reply-To: References: <20241021161418.0CD9677ED45@eggemoggin.niobe.net> <804b385a-2532-4b0d-8f26-edd4278bd3f7@oracle.com> Message-ID: <3ee5ea96-bd7e-423f-9236-dbc7f69222f2@oracle.com> On 10/22/2024 12:09 PM, Severin Gehwolf wrote: > On Tue, 2024-10-22 at 10:28 -0700, Alex Buckley wrote: >>> Every jlink in every JDK build can consume JMOD files. >> >> It would be helpful to state this. And then: "In addition, in some JDK >> installations, jlink can consume modules from the run-time image of >> which it is part. Whether jlink can do this depends on how its run-time >> image was built." > > OK. Thanks. Making basic statements about what jlink does is important because many readers are coming in cold. For example, they might be arriving from the top story on https://www.infoworld.com/software-development/ on October 22 2024: * Java proposal would shrink JDK by 25% * Plan would reduce the size of the JDK by enabling the jlink tool to create custom run-time images without using the JDK?s JMOD files. Most readers have never seen a JMOD file, but many will be aware that a modern JDK installation is comprised of modules, and a 25% drop in anything is worth reading about. If JEP 493 can spark the idea among readers that "Wow, there's a thing called jlink, which lets me make a smaller JDK from the JDK I already have!" then it's a success. Alex From pavelturk2000 at gmail.com Sat Oct 26 17:16:57 2024 From: pavelturk2000 at gmail.com (PavelTurk) Date: Sat, 26 Oct 2024 20:16:57 +0300 Subject: Can a parent layer use a child layer? Message-ID: Hello. I'm developing a multi-layered JPMS application. Let's say that in the boot layer, I have a car component (composed of several jars) that includes an engine (also made up of several jars). All child layers will interact with the car, but they should not have any access to the engine or its jars (classes). To achieve this, I want to place all jars related to the engine in a child layer, thereby hiding these jars and their classes from other child layers. However, I?m concerned that this setup results in the boot layer depending on a child layer, which seems to go against JPMS principles, where typically child layers depend on or use parent layers. My question is: does placing the engine in a child layer violate JPMS principles, and what would be the best approach in this situation? Best regards, Pavel From kasperni at gmail.com Sun Oct 27 09:24:42 2024 From: kasperni at gmail.com (Kasper Nielsen) Date: Sun, 27 Oct 2024 14:54:42 +0530 Subject: Can a parent layer use a child layer? In-Reply-To: References: Message-ID: Kasper Nielsen 14:54 (0 minutes ago) to PavelTurk Hi Pavel, Do you really need to use layers here. Can't you simply just export the needed classes from engine to car? module engine { exports com.engine.api to car; exports com.engine.internal to car; } module car { requires engine; } /Kasper On Sat, 26 Oct 2024 at 22:47, PavelTurk wrote: > > Hello. > > I'm developing a multi-layered JPMS application. Let's say that in the boot layer, I have a car component (composed of several jars) > that includes an engine (also made up of several jars). All child layers will interact with the car, but they should not have any access > to the engine or its jars (classes). To achieve this, I want to place all jars related to the engine in a child layer, thereby hiding these > jars and their classes from other child layers. > > However, I?m concerned that this setup results in the boot layer depending on a child layer, which seems to go against JPMS principles, > where typically child layers depend on or use parent layers. > > My question is: does placing the engine in a child layer violate JPMS principles, and what would be the best approach in this situation? > > Best regards, Pavel From pavelturk2000 at gmail.com Sun Oct 27 09:40:01 2024 From: pavelturk2000 at gmail.com (PavelTurk) Date: Sun, 27 Oct 2024 11:40:01 +0200 Subject: Can a parent layer use a child layer? In-Reply-To: References: Message-ID: Hi Kasper, The problem is that the component engine consists of many modules, and these modules were developed by different teams. Therefore, we need to hide the engine modules from other layers. After some consideration, I realized the core issue: JPMS doesn?t allow to hide (or make "private") modules within a layer using the layer controller. I?d like to open an issue to suggest adding this capability. By the way, I?m not sure why this feature wasn?t included from the start ? perhaps Alan Bateman can tell about it. Best regards, Pavel On 10/27/24 11:24, Kasper Nielsen wrote: > Kasper Nielsen > > 14:54 (0 minutes ago) > to PavelTurk > Hi Pavel, > > Do you really need to use layers here. Can't you simply just export > the needed classes from engine to car? > > module engine { > exports com.engine.api to car; > exports com.engine.internal to car; > } > > module car { requires engine; } > > /Kasper > > On Sat, 26 Oct 2024 at 22:47, PavelTurk wrote: >> Hello. >> >> I'm developing a multi-layered JPMS application. Let's say that in the boot layer, I have a car component (composed of several jars) >> that includes an engine (also made up of several jars). All child layers will interact with the car, but they should not have any access >> to the engine or its jars (classes). To achieve this, I want to place all jars related to the engine in a child layer, thereby hiding these >> jars and their classes from other child layers. >> >> However, I?m concerned that this setup results in the boot layer depending on a child layer, which seems to go against JPMS principles, >> where typically child layers depend on or use parent layers. >> >> My question is: does placing the engine in a child layer violate JPMS principles, and what would be the best approach in this situation? >> >> Best regards, Pavel From johannes.spangenberg at hotmail.de Sun Oct 27 11:45:53 2024 From: johannes.spangenberg at hotmail.de (Johannes Spangenberg) Date: Sun, 27 Oct 2024 12:45:53 +0100 Subject: Can a parent layer use a child layer? In-Reply-To: References: Message-ID: Hi Pavel, if I understand you correctly, your problem is that with the JPMS, you have no way to control which modules can be accessed by the child layers. > After some consideration, I realized the core issue: JPMS doesn?t > allow to hide (or make "private") modules within a layer It has been some years since I have last worked on code setting up module layers. So I might miss something, but I think it would makes sense to have more control here. However, note that I am just a fellow subscriber to this mailing list. For example if you create a plugin API, you may not want to expose all the (internal) modules of your application to the plugins. It is also not really viable to require all of your internal modules to only use qualified exports. Using qualified imports for this purpose also seems like a violation of Separation of Concerns. If you are using a library, it should not be the concern of the library whether you are providing a plugin API. > All child layers [...] should not have any access to the engine or its > jars (classes). How important is the enforcement during runtime? Before you go to great length to change the architecture of your application code, this is something you may want to think about. Consider that even if you prevent access to these modules, child layers may still cause havoc by calling System.exit(int) or other Java-methods with significant site effects. If you need to enforce this at runtime, an alternative solution might be to verify the modules in the child layers before loading them. I guess this might be done after resolving the Configuration. For named modules, it might be enough to look at ResolvedModule.reads(). However, I doubt that this will not work for automatic or unnamed modules in the child layer. For a third potential solution, the JPMS still allows you to use custom class loaders which I imagine could filter out classes from internal modules. However, if I remember correctly, the JPMS doesn't make it easy to build your own class loaders for a module layer. You might need to re-implement some JDK-internal code. > To achieve this, I want to place all jars related to the engine in a > child layer, thereby hiding these jars and their classes from other > child layers. However, I?m concerned that this setup results in the > boot layer depending on a child layer, which seems to go against JPMS > principles, While I am not entirely convinced by the maintainability of your idea based on your brief description, you can have a parent layer depending on a child layer. You just need to ensure that the API between both layers is defined in the parent (or some other common layer). From alan.bateman at oracle.com Mon Oct 28 09:33:32 2024 From: alan.bateman at oracle.com (Alan Bateman) Date: Mon, 28 Oct 2024 09:33:32 +0000 Subject: Can a parent layer use a child layer? In-Reply-To: References: Message-ID: <24f3845b-6c36-4332-8160-d2851053d3cd@oracle.com> On 26/10/2024 18:16, PavelTurk wrote: > Hello. > > I'm developing a multi-layered JPMS application. Let's say that in the > boot layer, I have a car component (composed of several jars) > that includes an engine (also made up of several jars). All child > layers will interact with the car, but they should not have any access > to the engine or its jars (classes). To achieve this, I want to place > all jars related to the engine in a child layer, thereby hiding these > jars and their classes from other child layers. > > However, I?m concerned that this setup results in the boot layer > depending on a child layer, which seems to go against JPMS principles, > where typically child layers depend on or use parent layers. > > My question is: does placing the engine in a child layer violate JPMS > principles, and what would be the best approach in this situation? I assume the concern is that engine exports its API to all modules. If car and engine were tightly coupled then engine could export its API to only car. It would be feasible to have the engine modules in a child layer and uses services but only if the engine API (its interface) is in the boot layer. So think about the engine API in the boot layer as a service and where the implementation is provided by a service provider module in a child layer. The code in car would use ServiceLoader to locate the implementation. Random modules in other child layers that want to use engine will be disappointed as there will be no implementation visible to their use of ServiceLoader. -Alan