2017-08-07 1 views
0

Je rencontre des problèmes avec les composants de la commande chargés lors de l'utilisation des services de déclarations OSGi via Karaf.Plusieurs références et dépendances avec des services déclaratifs

J'ai cette situation:

@Component 
public class A implements IA 
{ 
    doSomething() {...} 
} 


@Component 
public class B implements IB 
{} 

@Component 
public class C implements IC 
{ 
    @Reference 
    IA a 

    @Reference 
    (cardinality = ReferenceCardinality.MULTIPLE, 
    policyOption = ReferencePolicyOption.GREEDY, 
    unbind = "doUnRegister") 
    void doRegister(IB b) 
    { 
    a.doSomething() 
    } 

    void doUnregister(IB b) 
    { 
    ... 
    } 
} 

A, B et C sont trois faisceaux distincts.

Lors de la mise à feu de Karaf, un B est enregistré et doRegister est appelé. Cependant: le service A n'est pas prêt (a est nul).

J'ai essayé les éléments suivants:

  1. régler le niveau de départ de A à quelque chose inférieur à B ... N'a pas travaillé
  2. pour ramasser les enregistrements de B dans un travail liste et utiliser en fait une plus tard, quand C a été activé. N'a pas fonctionné et le code était encombré.
  3. recherché pour un moyen d'écrire cette exigence à travers l'annotation sur doRegister - pas possible.
  4. J'ai essayé d'utiliser un localisateur de service et d'obtenir le contexte grâce à une méthode d'activation sur C - N'a pas travaillé, il s'est écrasé Karaf.

Je dois clairement manquer quelque chose, y at-il quelqu'un qui a connu des problèmes similaires et trouvé une solution?

MISE À JOUR: Référence A a changée en IA a. Ajout d'informations oubliées sur la référence B().

+0

Vos classes d'exemples sont-elles complètes? Est-ce que B peut-être implémenter et interfacer et A non? –

+0

Merci de m'avoir signalé. Mais oui A, B, et, C sont soutenus par des interfaces et le problème demeure. –

+0

Pouvez-vous poster un petit exemple complet à github ou similaire? –

Répondre

0

Basé sur l'exemple de code que vous fournissez, C ne sera pas activé jusqu'à ce que A et B sont présents depuis les références à A et B sont des références statiques, obligatoires. Commencer donc à commander n'est pas pertinent.

De plus, les références sont définies dans l'ordre dans lequel elles sont écrites dans la description du composant XML. Lorsque Bnd traite les annotations dans la description du composant XML, il écrit les références dans l'ordre par le nom de la référence. Le nom de référence peut être défini explicitement et le nom du membre annoté par défaut. Donc, dans votre exemple de code, a vient avant doRegister, de sorte que le champ a sera défini avant que doRegister ne soit appelé. Je suppose que, dans votre effort pour réduire votre code actuel à cet exemple, vous avez perdu des informations importantes pour comprendre votre problème. Cela inclurait la nature statique/dynamique et obligatoire/facultative de votre référence ainsi que les noms de référence.

+0

MISE À JOUR: J'ai mis à jour le programme d'exemple avec plus de détails sur l'annotation de référence et l'utilisation correcte des interfaces. –

+0

RéférenceCardinality.MULTIPLE est 0..n. Donc, si le composant C commence avant le composant B, la référence de C à être sera heureusement satisfaite par zéro B. En outre, si vous regardez la description du composant généré XML pour le composant C, vous devriez voir l'élément de référence pour le champ A précéder l'élément de référence pour la méthode de rattachement doRegister. Cela signifie que A sera lié et qu'un champ sera défini avant que B ne soit lié et que doRegister ne soit appelé. –