Skip to content
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

core: Add support for ServiceLoader to the Core Framework #372

Open
bjhargrave opened this issue Oct 15, 2021 · 15 comments
Open

core: Add support for ServiceLoader to the Core Framework #372

bjhargrave opened this issue Oct 15, 2021 · 15 comments
Assignees
Milestone

Comments

@bjhargrave
Copy link
Member

We have a Service Loader Mediator spec. But it is not built into the framework and currently depends upon weaving.

I would like to explore adding support directly unto the framework for the Service Loader model. JPMS has direct support for the Service Loader model via uses and provides in the module-info file. JPMS has advantages since it is built into the java runtime, so we may not be able to do as well. But I suspect we can do better than the current Service Loader Mediator spec by building this function into the core framework.

@maho7791
Copy link
Contributor

I would support that as well, because the ServiceLoader Mediator requires its Capabilities to work properly.
Especially Jarkarta API's (JPA, JAXB, Jax-Ws, Websockets) make use of the ServiceLoader to find the Implementation. The OSGi Manifests often event dont have the Capabilities or they are not complete. Having this support in the core framework, would solve major pain points.

@bjhargrave bjhargrave self-assigned this Nov 10, 2021
@bjhargrave bjhargrave added this to the R9 Core milestone Nov 10, 2021
@laeubi
Copy link
Contributor

laeubi commented Mar 29, 2022

We have a Service Loader Mediator spec.

I once tried to use that but it seems not fitting very well because it seem to be limited to the use of ServiceLoader.load() calls but I must confess I never wanted to use it that way but the other way round: Accessing ServiceLoader specified services in an OSGi way

But I suspect we can do better than the current Service Loader Mediator spec by building this function into the core framework.

I once written a extender-bundle that simply discovers SPI in META-INF/services and registered them as plain OSGi services that's quite useful and could even be made lazy when using a ServiceFactory.

Especially Jarkarta API's (JPA, JAXB, Jax-Ws, Websockets) make use of the ServiceLoader to find the Implementation.

Jakarta can uses an OSGi-aware serviceloader that works quite well. I just always wondered why they did not simply delegate to standard java ServiceLoader.load() if nothing is found (it instead returns null then) this requires some care on the caller-side, but maybe this can server as an inspiration?

So if the osgi.util would contain such an ServiceLoaderHelper that OSGi could call to fnd SPIs in a standard compliant way that would be great.

@rotty3000
Copy link
Member

rotty3000 commented Mar 29, 2022

Service Loader Mediator automatically makes services OSGi service already provided you set the register directive which includes the type, which @ServiceProvider does for you. Since the spec lets you add arbitrary service properties via the Capability so does SPI Fly as does @ServiceProvider. Finally Aries SPI Fly let's you make prototype scope services by adding the property service.scope=prototype?

Furthermore, since the last few versions SPI Fly can be used without metadata in the provider/consumer bundles in question. You can force bundle(s) which do not have SLM requirements or capabilities using framework properties:

org.apache.aries.spifly.auto.consumers=<comma_delimited_bsn_globs>
org.apache.aries.spifly.auto.providers=<comma_delimited_bsn_globs> #here you can add service properties using OSGi package attribute syntax

All this needs better docs for sure.

@laeubi
Copy link
Contributor

laeubi commented Mar 29, 2022

@rotty3000 probably yes... I just failed to get it setup and the aries stuff often pulls in a lot of stuff, much more effort I want to spend for a simple lookup :-)

At least this "automatically makes services OSGi service already provided" has not worked well starting without a managed setup (e.g. karaf).

@rotty3000
Copy link
Member

SPI Fly can have as little as itself and OSGi as a dependency. (See org.apache.aries.spifly:org.apache.aries.spifly.dynamic.framework.extension:1.3.4). You do not need a managed setup for everything described above. You do however have to have the correct metadata.

@laeubi
Copy link
Contributor

laeubi commented Mar 29, 2022

@rotty3000 I'll give it another try nex time it becomes relevant, maybe I can use this for pax-jpa as well, maybe its just a matter of

this needs better docs for sure

are you a developer of the spi-fly project as well?

@rotty3000
Copy link
Member

yes I am, sadly I'm not in love with the tech Aries has migrated to for documentation. I find it very painful and this didn't help the fact that a lot of Aries docs were already extremely out of date. But that isn't your problem and it's not an excuse for poor docs...

@laeubi
Copy link
Contributor

laeubi commented Apr 2, 2022

@rotty3000 currently using JAXB in OSGi requires an OSGi-aware serviceloader do you think you can help the eclipse-ee4j people to add appropriate headers so it works with the spifly instead?

I'm also interested in replacing pax-jpa tracker with using spifly would that be possible?
The bundle simply needs every item declared in META-INF/services/javax.persistence.spi.PersistenceProvider as PersistenceProvider service.

@rotty3000
Copy link
Member

Hey @laeubi sorry for the delayed answer but I wanted to make a first pass to fix the SPI Fly documentation [1] so that I could use it to answer your question :D

Please review it to see if that helps you with JAXB (it's not very long). I've been using SPI Fly's auto properties [2] to handle JAXB in Aries JAX-RS whiteboard [3] successfully ever since this was implemented. In other words I didn't go the route of modifying the JAXB API or Implementation to add SLM requirements&capabilities but I still get a working system.

[1] https://aries.apache.org/documentation/modules/spi-fly.html
[2] https://aries.apache.org/documentation/modules/spi-fly.html#_dynamic_weaving_by_auto_properties
[3] https://github.com/apache/aries-jax-rs-whiteboard/blob/master/jax-rs.itests/itest.bndrun#L55-L56

@laeubi
Copy link
Contributor

laeubi commented Apr 3, 2022

No problem, I'll try to give it a try the next days, the documentation is much clearer now I think. I'm just a bit uncertain about JAX weaving versus the OSGi-Serviceloader, but this sounds interesting for cases where the consumer is not aware of OSGi..

There is just one use-case I feel missing (I hope it is ok to discuss this in the context of this issue, if not let me know a better place):

According to the docs I need to provide some framework properties, this seems rather "static" and I need to know the name of the bundles beforehand, also I don't see a way to limit the registration to some SPI interface.

What would be useful I think would be the following:

  1. I can define a Requirement in the Bundle-Manifest e.g. Require-Capability: java.util.ServiceLoader:="(service=javax.persistence.spi.PersistenceProvider)" (I hope I got the syntax right from here so feel fre to correct me if I'm wrong)
  2. Aries SPI-Fly would detect that header, track all bundles in the framework for any META-INF/services/javax.persistence.spi.PersistenceProvider and registers a ServiceFactory for each whose getService returns the instance (and null for all other bundles without that header)

@rotty3000
Copy link
Member

Hi @laeubi I think this is an interesting conversation. Could we take over to the Aries dev mail list or possibly in Aries JIRA?

@laeubi
Copy link
Contributor

laeubi commented Apr 5, 2022

@muthukumar1756
Copy link

muthukumar1756 commented Apr 2, 2024

Error executing command: Unable to resolve root: missing requirement [root] osgi.identity; osgi.identity=swiggy-feature; type=karaf.feature; version="[1.0.0.SNAPSHOT,1.0.0.SNAPSHOT]"; filter:="(&(osgi.identity=swiggy-feature)(type=karaf.feature)(version>=1.0.0.SNAPSHOT)(version<=1.0.0.SNAPSHOT))" [caused by: Unable to resolve swiggy-feature/1.0.0.SNAPSHOT: missing requirement [swiggy-feature/1.0.0.SNAPSHOT] osgi.identity; osgi.identity=org.apache.geronimo.specs.geronimo-jpa_2.2_spec; type=osgi.bundle; version="[1.1.0,1.1.0]"; resolution:=mandatory [caused by: Unable to resolve org.apache.geronimo.specs.geronimo-jpa_2.2_spec [203](R 203.0): missing requirement [org.apache.geronimo.specs.geronimo-jpa_2.2_spec [203](R 203.0)] osgi.serviceloader; (osgi.serviceloader=javax.persistence.spi.PersistenceProvider)]]

how to solve this error iam working on with the open jpa it requires the geronimo and the geronimo pom.xml has the require capability of osgi.serviceLoader

@rotty3000 @bjhargrave @laeubi @maho7791 how to solve this

@timothyjward
Copy link
Contributor

@muthukumar1756 - please open a new issue for usage questions. This issue is a design discussion for a new feature in the OSGi core specification.

@stbischof
Copy link
Contributor

may be done together with #685

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants