<div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Thu, Jan 9, 2025 at 12:05 PM Alex Buckley <<a href="mailto:alex.buckley@oracle.com">alex.buckley@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 1/9/2025 6:29 AM, David Lloyd wrote:<br>
> Sometimes it is desirable to load a plugin (for example) where the <br>
> module(s) in the plugin provide services but the plugin should be loaded <br>
> into a layer that is isolated from (i.e. a sibling to) the service- <br>
> consuming layer, which is generally a private implementation layer or a <br>
> peer plugin. <br>
<br>
We do not intend to provide isolation with the module system. We intend <br>
to provide strong encapsulation: If the plugin module does not export <br>
its provider code, then the JVM prevents access to that code by the <br>
service-consuming code (even if it's in the same layer and class loader <br>
as the provider code). We expect the framework which loads the plugin to <br>
arrange the exports of the plugin module as necessary to achieve this.<br></blockquote><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">I am not clear why the framework which loads the plugin is unable to use <br>
the JVM-backed access control mechanism to prevent consumers from <br>
accessing provider code directly.<br></blockquote><div><br></div><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">For a little bit of background: the access control mechanism by itself doesn't really give us anything that we _need_, per se, in terms of encapsulation. The security and integrity of a Quarkus application for example is not undermined if someone uses a non-supported Quarkus API in defiance of documentation. Having the access control is a "nice to have" for us, in that we can provide some extra steps for the user before they use non-supported APIs, just to make sure it's clear to them what they've signed up for in doing so.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">That said, we definitely will take advantage of the access control mechanism _as well_ if we can. But for us, isolation is _necessary_ due to the nature of these frameworks and the complexity of their environments. To give a simplified example, we sometimes run into situations where two extensions cannot coexist in one class loader because of various types of conflicts. This can be due to resources in the JAR, services provided, third-party libraries/transitive dependencies which conflict, etc. By isolating these extensions, we bypass these problems completely.</div></div><div><br></div><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">We define an environment for our users largely in terms of what APIs are provided by us for the user to consume. This is important because the user is free to bundle any module or JAR they want to include, as long as it is not one of the modules provided by us (note that I'm simplifying some of the nuance for the sake of discussion). But the other side of this coin is that we (or one of our extensions) may want to use a third-party library internally (say, a collections or algorithms library, for example) without making that part of the user's environment. The user should not have to care what modules we use internally, any more than a user cares what private methods exist on our implementation classes. The user might provide their own copy but a different version of the same algorithms library, for example. If we later decide to no longer use that library internally, the user should not know or care that the library has disappeared from our implementation, any more than if we had changed the implementation of a private method. This is in line with our philosophy of encapsulation which strongly emphasizes information hiding.</div></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><span style="font-family:Arial,Helvetica,sans-serif"><br></span></div><div class="gmail_default" style="">Apart from service binding, isolation works well with the platform module system in conjunction with class loaders. I've experimented with multiple approaches and am able to use the combination of module layer controllers and class loaders to do a variety of interesting things. In fact, more or less everything I have tried has worked well, including (for example) using automatic module descriptors to "modularize" classical JAR-based subsystems based on their Maven dependency information (and other factors). The fact that I can take such a subsystem and turn on module-based access controls, and they just work (other than service loading), is a good sign AFAICT. The extra API surface area that I would need from the JDK to make everything 100% functional is very small, but this change (or something equivalent) is an important part of it.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><span style="font-family:Arial,Helvetica,sans-serif"><br></span></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><span style="font-family:Arial,Helvetica,sans-serif">--</span></div></div><div dir="ltr" class="gmail_signature"><div dir="ltr">- DML • he/him<br></div></div></div>