[External] : Re: Inconsistency with service loading by layer or by class loader

David Lloyd david.lloyd at redhat.com
Tue Dec 17 16:18:29 UTC 2024


This argument is clearly not a good use of my time. I've responded to each
of your questions and given you everything you need to understand our use
case, and then some, but in response you are cherry-picking specific
arguments to derail my points. I'm going to go ahead and file a bug, PR,
and CSR instead, and continue the discussion with the people who have
actually worked on this code and its design.

On Tue, Dec 17, 2024 at 10:06 AM Ron Pressler <ron.pressler at oracle.com>
wrote:

>
>
> > On 17 Dec 2024, at 14:21, David Lloyd <david.lloyd at redhat.com> wrote:
> >
> >
> >
> > You're confusing the idea of modular encapsulation with the idea of
> platform integrity. I'm talking specifically about the encapsulation of
> modules that are loaded by a custom ClassLoader. If the user defines their
> own version of a string class which purports to be immutable, and that
> class is defined within my ClassLoader, then yes, I can mutate it if I want
> to. There are many ways to do this.
>
> The “platform integrity” is, itself, enforced by the same module
> capabilities available to libraries. The point is that modules give you the
> ability — which didn’t exist previously — to enforce your own invariants,
> not that you can *choose* not to enforce them. The choice not to enforce
> invariants is still available, what’s new is the ability to choose to
> enforce them.
>
> >
> > When I load a module in a class loader, I can basically do whatever I
> want with it, if I'm willing to do some tedious (and possibly
> performance-degrading) work. All I'm proposing is to make the work of doing
> *certain* things less tedious and performance degrading.
>
> Good, so because most programs will have just a single layer, we clearly
> have to focus on not making many modules per layer be
> performance-degrading. *That* seems to be the claimed core issue here.
>
> >
> > However, to give a counter-example, `Module` has `addUses` as well. But
> if I want to call `addUses` on behalf of a module I've defined, there is no
> corresponding `ModuleLayer.Controller` method so I do have to define the
> extra class, and that's a bit silly. This is an example of an easy
> enhancement that would not affect the integrity of the platform, would not
> significantly increase maintenance burden (since the logic would be nearly
> identical to its sibling methods), and would be easy to achieve.
>
> But to me this sounds like a sunk-cost argument. If the choice is between
> putting effort into supporting a rather baroque architecture, that itself
> is justified by a performance problem, wouldn’t it be better to focus on
> the performance problem, which could then support a much more common
> architecture and make the more baroque one unnecessary?
>
> If you could show how the performance issue materialises, that would be
> very helpful.
>
> >
> >
> > From our perspective, we started off with an open system, and the system
> has been made less and less open over time. Strictly speaking, the only
> "feature" here is fancy stack traces. Everything else arises out of adding
> restrictions. I'm not saying this to complain about modularity, but to
> remind you that we are presently only weakly incentivized to use modules at
> all, so dangling intangible "benefits" before me does not entice me much.
> We get more "features" by not using it. I'm essentially trying to be a team
> player here, but only out of a sense of cooperation.
>
>
> But I’m not trying to entice you to use a feature which may or may not be
> appropriate for your situation. I’m only presuming that since you seem
> interested in using the feature, you’re already incentivised.
>
> Modules add powerful capabilities with very important benefits to
> maintainability and security, and will likely add more benefits. These
> benefits are available to users who wish to enjoy them. The feature doesn’t
> exist to serve itself, and using it to tick a box if you don’t believe it
> helps you certainly doesn’t help us. The JDK already enjoys these benefits.
>
> >
> > I'm not sure yet. But I think so.
>
> I would advise against that. If there’s a problem with a more
> straightforward architecture, let’s try and resolve that.
>
> >
> > Imagine a layer of 1000 modules, packaged in JAR files. To load a single
> class from the layer, the layer must be defined. To do this, the graph must
> be resolved, and to accomplish that, the descriptors of every module must
> be created. To get the descriptors, each of the 1000 JAR files has to be
> opened and the bytes of the descriptors must be read from each one. Because
> of eager resolution, the load time of a module layer will always scale in
> linear proportion to the potential number of modules in the layer, no
> matter how optimized each step in the process is made to be. The only
> possible optimization strategies involve paring down the root set -
> something which requires ahead-of-time analysis which again would not be
> necessary if modules were loaded and linked lazily, like classes are.
> Loading modules on demand would solve this performance issue fairly
> decisively; it would also not forbid ahead-of-time assembly of a module
> graph if that is what the user wants.
>
> But the JDK has to support any reasonable number of modules in a single
> layer, as that’s the common case, anyway. There is no need to hypothesise.
> Either it works with acceptable performance or it doesn’t, and if it
> doesn’t, that requires addressing. Indeed, there’s significant ongoing
> effort on improving startup time, not just relative to modules’ current
> state, but relative to that of all Java applications, modular or otherwise.
>
> — Ron



-- 
- DML • he/him
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/jigsaw-dev/attachments/20241217/ce7851ae/attachment.htm>


More information about the jigsaw-dev mailing list