-
Notifications
You must be signed in to change notification settings - Fork 69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[POC] Add support for Java Service Loader in the OSGi core framework #853
base: master
Are you sure you want to change the base?
Conversation
As discussed in the last spec call it would be very handy if the OSGi core framework would allow native support for Java Service Loader (SPI) without to require any special handling or metadata like ServiceLoader Mediator (SLM) that currently require bytecode weaving. It is commonly used and a constant source of problems when used inside OSGi and beside SLM there are even other workarounds like the OSGi ResourceLoader especially in JakartaEE but this requires some brittle handling in the code of the bundle itself. It is therefore the aim to actually have a simple and native integration in the OSGi core framework making use of how the SPI works and the internal knowledge of the OSGi Framework implementation that is usually not accessible to the outside. This demonstrates such implementation in the following way: - Whenever resources are requested that starts with "META-INF/services/" then it is detected by the framework - The interface/class of the SPI is extracted and loaded by the bundle, and then checked if any other bundle is currently wired to this (e.g. by import package) - For all such bundles it is checking for the same resource to be present and return them as if they where part of the same bundle - Additionally all classnames mentioned in such resources are recorded and linked to such bundle - If later a classload occurs and nothing is found in the bundle itself as a last resort it checks this mapping if a SPI class has to be loaded from the foreign bundle All this works without having both bundles to declare anything special or knwo of each other, the only connection is a compatible SPI type and the presence of the corresponding "META-INF/services/" and a SPI lookup performed.
Isn't this 'just' #295 built into the framework and ignoring the service-loader capabilities and requirements to avoid the need to specify them? |
Yes, we have had some discussion in the last spec call if the OSGi-core specification should probably have direct support for the Java Service Loader but then it should:
therefore I now baked this directly into the framework for demonstration purpose on how a framework implementation could use its internal knowledge to support the serviceloader natively. If it would become part of the spec, then we of course can still implement it by a (default shipped) Equinox extension and that's also why I have not implemented it in detail, it should just show the concept used in #295 |
The problem being solved here really is a recurring hassle for me. This problem is especially challenging when Orbit needs to bundlize plain-old jars because who knows what inner workings are involved without deeply inspecting the source code. So I end up doing purely evil things like this:
For the batik case, downstream consumers were doing other nasty kinds of workarounds like providing a fragment to make the lookup work or using reflection to inject the registrations. Horrible! 😱 🤯 |
As discussed in the last spec call it would be very handy if the OSGi core framework would allow native support for Java Service Loader (SPI) without to require any special handling or metadata like ServiceLoader Mediator (SLM) that currently require bytecode weaving.
It is commonly used and a constant source of problems when used inside OSGi and beside SLM there are even other workarounds like the OSGi ResourceLoader especially in JakartaEE but this requires some brittle handling in the code of the bundle itself.
It is therefore the aim to actually have a simple and native integration in the OSGi core framework making use of how the SPI works and the internal knowledge of the OSGi Framework implementation that is usually not accessible to the outside.
This demonstrates such implementation in the following way:
All this works without having both bundles to declare anything special or knwo of each other, the only connection is a compatible SPI type and the presence of the corresponding "META-INF/services/" and a SPI lookup performed.
See
FYI @tjwatson @fipro78
An example project can be found here:
osgi-core-service-loader-example.zip