osgi: à l'Aide de ServiceFactories?
Je suis en train d'essayer d'obtenir un simple paquet contenant un Service à l'Usine en cours d'exécution.
C'est ma classe factory:
public class SvcFactory implements ServiceFactory<ServiceB> {
@Override
public ServiceB getService(Bundle bundle,
ServiceRegistration<ServiceB> registration) {
return new ServiceBImpl();
}
@Override
public void ungetService(Bundle bundle, ServiceRegistration<ServiceB> registration,
ServiceB service) {
}
}
C'est mon service qui doit être créé par l'usine de:
public class ServiceBImpl implements ServiceB {
private ServiceA svcA;
public void setA(ServiceA a) {
svcA = a;
}
}
Et enfin la OSGI-INF/component.xml
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="bundleb.internal.SvcFactory">
<implementation class="bundleb.internal.SvcFactory"/>
<reference bind="setA" cardinality="1..1" interface="bundlea.ServiceA" name="ServiceA" policy="static"/>
<service servicefactory="true">
<provide interface="bundleb.ServiceB"/>
</service>
</scr:component>
Si je lance mon test de faisceaux (A, B et C) au sein de l'équinoxe j'obtiens l'erreur suivante:
org.osgi.framework.ServiceException: org.eclipse.equinox.internal.ds.FactoryReg.getService() returned a service object that is not an instance of the service class bundleb.ServiceB
Je ne trouve pas beaucoup d'informations sur l'utilisation ServiceFeactories déclaré dans un composant définition sur internet. Même le livre "OSGi et Équinoxe" ne m'a pas dit beaucoup sur leur utilisation.
Quelqu'un pourrait-il m'expliquer ce que je fais mal?
- le bundle contient votre service ne devrait pas avoir le ServiceB.class fichier. Si elle, elle serait d'utiliser différents ServiceB pour les différents bundle -- c'est faux.
- Je pense que vous avez mal compris. Si vous spécifiez le servicefactory attribut, puis DS va créer une nouvelle instance pour chaque module. Vous pouvez obtenir le paquet que vous ont été attribués à partir du ComponentContext.
Vous devez vous connecter pour publier un commentaire.
Il est en réalité assez simple ... DS crée une instance pour chaque paquet, donc avec DS vous de ne pas mettre en œuvre le Service d'Usine, DS fait tout le travail dur. Par exemple:
À chaque fois un autre bundle obtient cette XyzService, DS va créer une nouvelle instance. Vous pouvez utiliser le ComponentContext (éventuellement transmis à la méthode activate) pour obtenir le bundle qui est à l'aide de vous.
ServiceFactory
permet à votre code d'offrir un service personnalisé objet pour les différents faisceaux. Notez qu'avecServiceFactory
, les clients de votre service ne sont pas encore contrôle lors de la nouvelle instance est créée, ils service de recherche par son interface (ServiceB
) comme d'habitude. Donc, pour eux, il n'y a pas de différence, si votre service est enregistré commeServiceFactory
ou pas.Avec déclarative services, vous ne devez pas mettre en œuvre
ServiceFactory
vous-même. Juste ajouterservicefactory="true"
attribut à la<service>
élément (vous l'avez déjà fait) et les différentes instances de la classe de votre composant va être créé (activé) automatiquement à la requérante de faisceaux. Vous devez spécifierServiceBImpl
comme une classe d'implémentation du composant.