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

Ron Pressler ron.pressler at oracle.com
Mon Dec 16 16:40:30 UTC 2024


I am very much trying to understand the points you’re raising, but the scenario of a dynamic container you’re describing is complicated, and I’m trying to get to the bottom of the issue.

So far I’ve seen two components of concern. The container itself and some regular library that is loaded by the container and uses a ServiceLoader.

Now, when Alan suggested "Have you looked at changing these frameworks to work with modules and specify a module layer to ServiceLoader.load?” you responded that “frameworks” — the container and/or the regular ServiceLoader-using library — need to work both on the module path and the classpath, which is what piqued my interest, as I’m interested in the JDK’s runtime configurations.

For the sake of simplicity, let’s say that the container itself is modular and is only ever used on the module path, and put aside the question of why this should or shouldn’t be the case. We’ll focus on the “regular” ServiceLoader-using library.

Being a regular library, it doesn’t itself construct module layers and it creates a ServiceLoader of the ClassLoader variety.

Is the problem you’re describing that of the regular library not being able to find one of its service providers because that service provider would have been placed by the container in a separate module layer to that of the library itself?

If so, can you describe how that situation could arise? To prove to you that I am trying to understand your situation, here’s how I think that might happen:

Say the library in question is a logging facade that relies on logging service providers, and it happens to be used by both the user application and the container. Because it is used by the container, the container will load the library, and its logging provider in some container layer. But when the library is loaded again by the user application, in some user application layer, that copy won’t find the provider in the container’s parent layer.

Is that the situation you’re describing?

— Ron



> On 16 Dec 2024, at 15:18, David Lloyd <david.lloyd at redhat.com> wrote:
> 
> 
> 
> On Mon, Dec 16, 2024 at 9:05 AM Ron Pressler <ron.pressler at oracle.com> wrote:
> 
> 
> > On 16 Dec 2024, at 14:01, David Lloyd <david.lloyd at redhat.com> wrote:
> > 
> > 
> > No, they don't, because the users we are talking about are generally using a packaging solution of some sort. They have *some* control. They don't have *full* control unless they're ready to break things. It's like saying they have full control over what native libraries the JDK is using. It's *technically* true. But in practice they're not going to mess with low level stuff like that.
> 
> Ah, so that’s what I was looking for. Clearly, -p is no more low level than -cp. But what you’re saying is that there is something that mediates between the application author and the runtime configuration — let's call that a build tool — and that build tool knows how to output -cp but not -p, even though, from the design of the JDK, the two are equally easy.
> 
> That is as I suspected, and the build tool problem is one we’re aware of. We have some ideas in mind, but they don’t concern modules’ design directly.
> 
> No, I think you still misunderstand. This does not have anything to do with the build tool. The launcher is not used to build the application, and the build tool is not used to build the launcher, at least in the general case. The launcher is a separate thing.
> 
> > Yes, we are in fact talking about regular libraries, or at least, that's what I'm talking about: regular libraries which use ServiceLoader running within dynamic containers.
> 
> According to what Alan said, a regular library that uses ServiceLoader that runs within a dynamic container would work just fine if the container uses ModuleLayers. It is only the container itself that would need to require being put on the module path.
> 
> Now, with this context, go back and re-read the beginning of the email thread where I explain why this is not in fact true.
> 
> > The application author is not using `-cp X.jar` or `-p X.jar` because in most cases, the application author is either not launching with Java at all (i.e. they're launching a container startup script), or they're going to launch an uberjar or some special launcher that sets up a class loading environment and bootstraps the application, following the instructions provided by the container (today this might just be e.g. `java -jar startup.jar` but again, in most cases this will be wrapped up in a script of some sort).
> 
> But a script contains -p just as easily as it does -cp. Anyway, we’re getting back to the build tool problem.
> 
> It doesn't matter what the launcher script does, it matters what the class loader does.
> 
> > You could, and that might work in many cases, maybe even most cases. Few third party library authors are going to do that though, especially if there isn't a standard blob of code to do that for them.
> 
> Very, very, few library authors would ever need to do this. We’re talking about, at most, one in ten thousand libraries. Only containers, really.
> 
> No, we're still talking only and specifically about third-party libraries which use ServiceLoader. However this meta-debate with you is getting nowhere, so I'm inclined to end it unless there is evidence of you trying in good faith to understand what I'm saying, and accepting - on faith perhaps - that this use case, based on software that has been widely adopted within the ecosystem for over two decades, is in fact valid and does exist, rather than constantly redefining and trivializing everything I say.
> -- 
> - DML • he/him



More information about the jigsaw-dev mailing list