5 votes

Impossible de trouver le service car le paquet OSGi n'est pas activé

J'ai un problème pour découvrir les services fournis par certains bundles OSGi qui ne sont pas activés. Permettez-moi de décrire la situation :

  • L'ensemble A définit l'interface X
  • Les offres groupées B, C et D fournissent des services qui mettent en œuvre l'interface X
    • Les services de ces bundles sont enregistrés via Spring DM, ils ne sont donc créés que lorsque le bundle est activé et que Spring DM initialise le contexte d'application défini dans le bundle.
  • L'offre groupée A est activée et, à un moment donné, elle demande au registre de services s'il existe des services pour l'interface X. Elle n'en trouve pas, car les offres groupées B, C et D ne sont pas passées à l'état ACTIF (elles sont seulement RESOLUES).

Je ne parviens pas à faire démarrer les lots B, C ou D, et donc à enregistrer leurs services. Je les force à démarrer en les ajoutant à la liste des services de config.ini n'est pas une option, car il peut y avoir n'importe quel nombre de bundles installés dans l'application (via un mécanisme de mise à jour de type Eclipse p2) qui implémentent l'interface X.

L'application est une application RCP basée sur Eclipse 3.5, utilisant Spring 2.5.6 et Spring DM 1.2.1.

Comment forcer l'activation de ces offres groupées ?

6voto

Mark Elliot Points 31871

Ce que vous avez vraiment, c'est un problème de hiérarchie de dépendance, et la solution que vous proposez n'est qu'un pansement sur le problème sous-jacent.

Ce que vous devriez vraiment considérer, c'est l'architecture de votre système, car ce que vous avez, c'est une dépendance circulaire (voir la discussion dans les commentaires de votre message original). Vous avez (qu'on le veuille ou non) A qui requiert des services de (et dans un certain sens dépend de) B et C. Pendant ce temps, B et C dépendent directement de A, et en tant que tel, ne peut pas commencer jusqu'à ce que A apparaisse.

Dans le meilleur des cas, vous pouvez écrire du code dans B et C pour vérifier l'existence de A, mais cela ne fait que masquer (comme je l'ai mentionné) le problème sous-jacent. Ce que vous devriez vraiment envisager, c'est de diviser A en deux paquets, appelons-les A1 et A2.

A1 doit fournir l'interface dont B et C ont besoin (dépendent). A2 doit disposer d'auditeurs pour les services dont dépendent B et C. Au démarrage, si B et C sont des services requis, A1 doit être exécuté, mais A2 peut démarrer à tout moment par la suite, et tout devrait fonctionner.

0voto

Nix Points 987

Je pense avoir trouvé la solution à ce problème, même si elle semble un peu bricolée.

Je suis tombé sur ce fil où Adrian Colyer a laissé entendre qu'un "observateur de paquets" externe pourrait être chargé d'activer les paquets lorsqu'ils sont installés dans le cadre.

Ma solution a donc été la suivante :

  • Ajouter un en-tête personnalisé aux manifestes respectifs des lots B, C et D, par exemple "MyApp-AutoStart : true"
  • Créer un écouteur de bundle qui répond lorsqu'un bundle passe à l'état RESOLVED, et recherche l'en-tête
  • Si la valeur de l'en-tête est "true", l'auditeur de la liasse appelle bundle.start()

Grâce à cette méthode, les paquets que je souhaite voir démarrer le sont sans avoir à recourir à la fonction config.ini Ils peuvent aller et venir à leur guise, mais leurs services sont disponibles lorsqu'on les interroge.

0voto

Leen Toelen Points 258

Jetez également un coup d'œil à felix fileinstall, qui surveille un répertoire à la recherche de bundles et les installe et les démarre automatiquement. Lorsqu'un fichier est supprimé, l'ensemble est arrêté et désinstallé également.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X