In OSGi, ServiceLoader.load fails to find an implementation
Asked Answered
B

0

9

We have been trying to get SPI Fly to work with openstack4j-core and one of the openstack4j connectors (openstack4j-httpclient). It is org.openstack4j.core.transport.HttpExecutorService that require the SPIFly weaving.

One quirk: both bundles are loaded from a zip file and started after the rest of the system is up and running. The same zip file provides the org.apache.aries.spifly.dynamic.bundle.

The two bundles do use the OSGI-Spec compliant model from the standard set of instructions for SPI Fly. Per these instructions, all we really need is the appropriate Require-Capability and Provide-Capability headers in the MANIFEST.MF of both bundles, plust the service declaration under META-INF/ (shown below).

The core bundle has:

Require-Capability: 
osgi.serviceloader;filter:="(osgi.serviceloader=org.openstack4j.api.APIProvider)";cardinality:=multiple,
osgi.serviceloader;filter:="(osgi.serviceloader=org.openstack4j.core.transport.HttpExecutorService)";cardinality:=multiple,
osgi.serviceloader;filter:="(osgi.serviceloader=org.openstack4j.openstack.logging.LoggerFactorySupplier)";cardinality:=multiple;resolution:=optional,
osgi.extender;filter:="(osgi.extender=osgi.serviceloader.processor)",
osgi.extender;filter:="(osgi.extender=osgi.serviceloader.registrar)",
osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.7))"

And the httpclient one has:

Require-Capability: osgi.extender;filter:="(osgi.extender=osgi.serviceloader.registrar)",osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.7))"

Provide-Capability: osgi.serviceloader;osgi.serviceloader="org.openstack4j.core.transport.HttpExecutorService"

(Re-formatted for readability, of course)

Additionally, the openstack4j-httpclient has the file named org.openstack4j.core.transport.HttpExecutorService under META-INF/services, with the single line:

org.openstack4j.connectors.httpclient.HttpExecutorServiceImpl

We also add the org.apache.aries.spifly.dynamic.bundle bundle, which provides the serviceloader.processor and serviceloader.registrar capabilities.

Then at runtime, the ServiceLoader call just does not find the HttpExecutorService.

PS: Messing with the order in which the bundles are started has not been fruitful and calling resolveBundles on FrameworkWiring before all the bundles are started has not worked.

Barbital answered 7/2, 2018 at 23:12 Comment(1)
Are there any errors or relevant log messages in the OSGi LogService?Congruous

© 2022 - 2024 — McMap. All rights reserved.