I want to solve the following problem and need advice, what the best solution is.
I have a bundle A in which a service interface X is defined. A bundle B provides a service implementation of X and contributes the implementation to the tool. A and B use Google Guice and Peaberry to configure the setup of the objects.
There are two possibilities I can use to contribute the service implementation:
- Using an eclipse extension: In this solution I can use the GuiceExtensionFactory mechanism of Peaberry to create the service implementation using Guice and therefore can inject stuff needed by the implementation. The disadvantage here is that in the bundle defining the extension point, I need the boilerplate code for the resolution of the extensions because there is to my knowledge no way to get the extensions injected into the class which uses the extensions. This looks like this:
<extension point="A.service.X">
<xservice
...
class="org.ops4j.peaberry.eclipse.GuiceExtensionFactory:B.XImpl"
.../>
</extension>
<extension
point="org.ops4j.peaberry.eclipse.modules">
<module
class="B.XModule">
</module>
</extension>
but I need the boilerplate code like this:
private List<X> getRegisteredX() {
final List<X> ximpls = new ArrayList<>();
for (final IConfigurationElement e : Platform.getExtensionRegistry().getConfigurationElementsFor( X_EXTENSION_POINT_ID)) {
try {
final Object object = e.createExecutableExtension("class"); //$NON-NLS-1$
if (object instanceof X) {
ximpls.add((X) object);
}
} catch (final CoreException ex) {
// Log
}
}
return ximpls;
}
- Using an OSGI service: My main problem here is to ensure that the service is registered. I want the bundle loaded lazily, so at least an access to one of the classes of the bundle is required. Registering the service programmatically using Peaberry has an issue, because nobody ever asks for a class of the bundle. The solution is to provide the service as a declarative service, but I do not know a way to create the service implementation in a way, that I can use Guice to inject required objects.
So I have some questions:
- Is there something I do not know so far that implements the code needed to read the extensions at an extension point generically and allows to inject the extensions to the class using the extensions?
- Is there a way to ensure that the service is provided even if it is added using the standard Peaberry mechanism, i.e., the bundle is activated when the service is requested?
- Is there a way like the GuiceExtensionFactory for declarative services, so that the creation of the service implementation can be done by the injector of the bundle? Something that look like:
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="Ximpl">
<implementation class="some.generic.guiceaware.ServiceFactory:B.Ximpl"/>
<service>
<provide interface="A.X"/>
</service>
</scr:component>
Summarized, I want a service implementation generated by Guice and I want to get the service implementations simply injected into the classes using the service without extensive boilerplate code. Has anybody a solution for that?
Sorry, to ask, but I searched the web for quite a while and so far I did not find a solution.
Thanks and best regards, Lars