2010-11-24 18 views
1

Dans notre projet (Osgi, Spring-Dm, Apache-Felix), nous avons un problème de production lorsque BundleContext.getService() renvoie null. Cela arrive très rarement, et pas au début, donc ce n'est pas un problème de mauvaise configuration.Osgi getService()

Une alternative pourrait être d'utiliser ServiceTracker pour localiser le service, mais parce que l'erreur est assez rare, je ne suis pas sûr si le changer résoudrait la situation.

+0

Avez-vous pensé à utiliser iPOJO avec felix? Il enlève la plupart des maux de tête en traitant des appels Osgi de niveau inférieur. –

+0

en fait non. pourrait être utile d'enquêter. – Uberto

Répondre

2

La spécification OSGi dit que la méthode retourne

  • Un objet de service pour le service associé avec référence
  • ou null si
    • le service n'a pas été inscrit
    • le service objet renvoyé par un ServiceFactory n'implémente pas les classes sous lesquelles il a été enregistré
    • l'ServiceFactory a lancé une exception

Ma première hypothèse serait que le service ne soit pas enregistré. Par ailleurs, l'utilisation de Spring-DM devrait rendre inutiles la plupart des accès programmés au registre de service. Au moins dans nos entreprises, ces appels ont généralement été interdits et ne sont autorisés que dans le code technique de niveau inférieur.

+0

En supposant (et en supposant que c'est un manque d'enregistrement), il pourrait s'agir d'une condition de course étrange ou d'un délai d'expiration. Les systèmes de composants distribués ont tellement de types de modes de défaillance. :-( –

+0

si c'est un manque d'enregistrement il doit y avoir quelque chose d'étrange qui se passe parce que la plupart du temps cela fonctionne (c'est un serveur de repos). De toute façon j'explorerai si nous utilisons correctement spring-dm. – Uberto

1

Uberto, ce n'est pas du tout bizarre que le service ne soit pas encore enregistré. OSGi est dynamique. Les services vont et viennent. Si vous essayez d'accéder à un service avant qu'il ne soit enregistré, vous obtiendrez null.

Lorsque vous effectuez un getService() brut, vous êtes en quelque sorte supposer que le service existe déjà. Si vous avez besoin que le service soit là, vous devriez plutôt faire quelque chose qui implique d'attendre l'événement d'enregistrement. Cela peut être fait avec ServiceTracker, mais c'est plutôt bas niveau. Comme d'autres l'ont fait remarquer, utiliser quelque chose comme Spring-DM ou Declarative Services rend cela assez facile et robuste.

0

Je peux confirmer que des conditions de concurrence peuvent se produire si vous utilisez le ServiceTracker! Parfois, le ServiceTracker ne peut pas attraper un Service même si le service est enregistré. Pour résoudre le problème j'utilise waitForService() au lieu de getService().

Cordialement Roland