[External] : Re: Inconsistency with service loading by layer or by class loader
Ron Pressler
ron.pressler at oracle.com
Sun Dec 15 14:24:29 UTC 2024
> On 14 Dec 2024, at 19:31, David Lloyd <david.lloyd at redhat.com> wrote:
>
>
> I'm honestly baffled by your question, because it indicates that you probably haven't really read or understood the entirety of my message, though I tend to be pretty wordy so I acknowledge that I'm at least partially to blame if that is the case.
Complaints related the configuration of the runtime are brought up from time to time. When I try to get to the bottom of the issue, people often get frustrated because they think the answer is obvious and I rarely get an answer.
> You phrase the question as if users were being rebellious against some broadly accepted natural order of things, which does not reflect any reality that I or my colleagues are aware of. But to answer the question at exactly face value: the user typically doesn't even know the difference. Many users don't ever launch an application using the `java` launcher outside of university. They're running a Quarkus application, or deploying into WildFly or Tomcat, or launching via JBang, or running in Spring Boot, or maybe running a prepackaged application, or any one of dozens of other ways that an application can be packaged and deployed. A user doesn't usually have any idea about whether the class loader which loads their classes is setting them up as a named module or just defining classes the old fashioned way.
Who is the user and what are the classes in this case? For one, 99.99% of classes don’t need to care whether they reside in a named or an unnamed module. For another, the application author does have full control over every JAR they list on the command to put it in a named or an unnamed module.
But right now, I don’t think we’re talking about arbitrary libraries (or application classes). We’re not even talking about “regular" libraries that use a ServiceLoader. We’re talking about “container” frameworks with a plugin system using ClassLoaders/ModuleLayer isolation. Such frameworks are important cornerstones of the ecosystem, but they make up maybe 1 in 10,000 libraries. It is only they who need to confront the class/module path decision.
Let’s call such a container framework X. There's at most one, maybe two, such frameworks in an application. Unless I misunderstand the situation, framework X — where the difficulty lies — is not itself loaded dynamically by WildFly or JBoss. Rather, it is loaded directly by the application (i.e. X *is* WildFly or JBoss). And here’s my question:
To use X, the application author needs to configure the runtime (on the launcher command line) to load X.jar, where “X.jar" would typically stand for multiple service provider JARs. For some years, applications had to configure the runtime to load X like this `-cp X.jar`. You’re not complaining about that. But when I suggested you tell the application author to configure the runtime to load X with `-p X.jar` rather than `-cp X.jar` you seemed to claim that this is almost impossible and that `-cp X.jar` must also work. Why?
Is it because the application author would write `-cp X.jar` out of habit? Is it because the application author uses some build tool to construct the runtime configuration and is unable to tell the build tool to configure `-p X.jar`? I once asked a maintainer of such a framework this question and his answer was, “all my users are familiar with -cp, but many have not used -p before and I’m afraid they’ll find it weird/confusing.” Would that be your answer, too?
>
> It's not really feasible to expect library authors to detect whether they are going to be run as a module or not, particularly if they have many entry points, as they sometimes do. They could for example add a run time check on every entry point, or on the class initializers of every entry point class.
But this isn’t needed in 99% of cases, and we’re not talking about “library authors” in general. We’re talking about a handful of large (and important) frameworks. Even if such a framework doesn’t also provide the single entry point to the program, can’t you put the test in the same place you first create the ServiceLoader, which I expect would detect the misconfiguration quite early in a plugin-based framework?
— Ron
More information about the jigsaw-dev
mailing list