Details
-
Improvement
-
Status: Open
-
Major
-
Resolution: Unresolved
-
None
-
None
-
None
Description
This was already described here to give more context:
Sometimes I would like to use an SPI but in a more OSGi way, where calling the ServiceLoader directly does not suffice:
- Bundles can come and go, so even if I have called the ServiceLoader once, there might be more because of new installed bundles, or some might go
- Currently I need to know the bundle names in advance when using auto-properties or I need to configure very broad filters that might affect more parts of the system as desired, also changing these properties most ly require a reboot of the framework to be detected
- I always has to know beforehand what/if a bundle requires an SPI, there is no way of a bundle to tell its requirements
- I can't tell if only certain SPI should be registered
On the other way OSGi aware bundles has well known techniques to solve such problems:
- OSGi Services can be tracked if the come and go
- Bundles can declare requirements that are then fetched by extenders to do the work on behalf of the bundle
What would be useful I think would be the following:
- I can define a Requirement in the Bundle-Manifest e.g. Require-Capability: java.util.ServiceLoader:="(service=my.spi.ServiceInterface)", maybe wildcards or a multi-property would be useful here. This would then be similar to DS.
- Aries SPI-Fly could track all bundles in the framework for any META-INF/services/javax.persistence.spi.PersistenceProvider and registers a ServiceFactory for each whose getService returns an instance for any bundle defining a matching header (and null for all other bundles without that header)
This has the advantage that a bundle can declare its intend to use SPI as regular service, and Aries takes care of tracking bundles, offering services and the consumer bundle only needs to use regular servicetrackers, DS, Blueprint, .. to track the service.
Even better, OSGi first approaches could simply register such a service and don't need to care about SPI at all if the like to enhance such a bundle.
One example where it would be usefull is pax-jpa where we need to track javax.persistence.spi.PersistenceProvider's.
The implementation can't know beforehand how these bundles are named, and we can't know when they are started or stopped, but because the PeristencaManagerFactory depends on the PersistenceProvider is crucial to unregister/shutdown PeristencaManagerFactory whenever the suppling bundle goes, or boot them up if a suitable one is installed. Beside that they are most of the time registered through the servicloader mechanism so a first approach was to provide a "wrapper" that for each persistence provider register it as a service, but this is a maintenance nightmare, as one need to know of course all the providers, need to write an additional bundle for each, update the dependencies on new version and so on.
Becuase of this, pax-jpa includes a PersistenceProviderBundleTrackerCustomizer that might can be used as a starting point here for a more generic implementation.