Question

Une fois qu'une instance d'un service OSGi est récupéré à partir du contexte de paquet devient-il invalidés lorsque le service est arrêté?

Mes premiers tests montrent que l'instance de service peut être utilisé même après que le faisceau de service est arrêté, ce qui contredit ma compréhension de la nature dynamique de OSGi.

Je suppose que cela se résume à ce que la récupération d'un service (via ServiceTracker) d'un autre paquet dans le conteneur OSGi ne fait, elle ne crée une nouvelle instance ou elle vous donne un pointeur vers l'instance qui est enregistré dans le conteneur?

Y a-t-il des dangers à l'aide de l'instance de service après que le service a été arrêté?

Était-ce utile?

La solution

Ceci est une très bonne question, donc je fouillai dans le cahier des charges à la recherche d'une réponse définitive. Il se trouve qu'il ya une section entière à parler de ce problème - voir la section 5.4 Stale Références à partir de la page 132 de OSGi Plate-forme de base Spécification, version 4, la version 4.2 .

Pour répondre à votre question selon les spécifications:

  

Le comportement d'un service qui devient non enregistrée est indéfinie. ces services   peut continuer à fonctionner correctement ou jeter une exception à leur discrétion.

Et pour éviter les problèmes potentiels:

  

Les paquets doivent écouter les événements générés par le cadre pour nettoyer et enlever rassis   références.

La spécification donne également des conseils sur la manière de minimiser les conséquences des références obsolètes.

Autres conseils

Vous avez raison en ce qu'elle est en contradiction avec la nature dynamique de OSGi. Je crois qu'il n'y a aucune garantie que le service sera disponible, bien que différentes implémentations de conteneurs OSGi et les services eux-mêmes peuvent se comporter différemment.

Par exemple, si le service a été créé et enregistré Spring DM, le service récupéré est en fait une procuration à base de printemps à la mise en œuvre sous-jacente, et la mise en œuvre peut encore disparaître. Ainsi, une référence de service qui fait directement référence à une mise en œuvre peut garder cet objet d'être enlevé, alors que la référence à base de proxy ne sera pas.

La spécification OSGi dit:

  

Bundles sont des entités qui sont visibles   dans la programmation de l'application normale. Pour   par exemple, lorsqu'un paquet est arrêté, tout   ses services seront enregistrés.

Vous ne devriez pas être en mesure d'obtenir un service d'un faisceau arrêté. Mais techniquement, il peut être possible de l'utiliser, au moins aussi longtemps que vous détenez une référence à l'objet de service (personne ne peut le prendre loin de vous et il ne sera pas GC'd). Mais je ne pense pas qu'il est sauf d'utiliser le service. Il peut dépendre d'autres ressources, bundle qui ne sont pas disponibles après que le paquet est arrêté.

  

Une fois qu'une instance d'un service OSGi est   récupérées à partir du contexte de paquet ne   il devient invalidée lorsque le service   est arrêté?

Non, la référence elle-même ne devient pas invalidée. Tant que quelque chose dans le conteneur tient, il peut pas non plus être GC'ed.

Cependant, si oui ou non il sera toujours utile, ne dépend que de la mise en œuvre du service lui-même, pas le contenant.

  

Mes premiers tests montrent que l'instance de service peut être utilisé même après que le paquet de service> est arrêté, ce qui contredit ma compréhension de la nature dynamique de OSGi.

Les spécifications s'indiquent que ces références ne doivent pas être tenus, mais il est à l'implémenteur de prendre soin de mettre en œuvre les spécifications correctement; signifie qu'il n'y a pas de contradiction, il n'y a que le fait que vous pouvez mettre en œuvre et déployer des faisceaux qui ne se comportent pas correctement selon les spécifications.

  

Je suppose que cela se résume à ce que la récupération d'un service (via ServiceTracker) d'un autre paquet   dans le conteneur OSGi ne fait, ne crée une nouvelle instance ou elle vous donne un pointeur   à l'instance qui est enregistré dans le conteneur?

Le conteneur ne crée pas de nouveaux cas de services, sauf s'il y a un ServiceFactory impliqué (voir spécifications). Vous cherchez un service, vous devez toujours donner un pointeur vers l'instance enregistrée dans le conteneur.

  

Y a-t-il des dangers à l'aide de l'instance de service après que le service a été arrêté?

Cela ne dépend de la mise en œuvre du service; cependant, en le faisant dans un paquet, vous créez automatiquement un paquet qui est conforme aux spécifications.

Dans la pratique, sont mis en œuvre de nombreux services pour libérer des ressources et des références et ne répondra pas correctement plus longtemps.

En ce qui concerne votre question de savoir s'il est dangereux d'utiliser une instance de service après que le service a été arrêté. Pour citer à partir de la spécification 4.2 de noyau (5.4 Références rassis):

  

Le comportement d'un service qui devient   non enregistrée est définie. Tel   les services peuvent continuer à fonctionner correctement   ou jeter une exception à leur   discrétion.

Je ne veux pas citer toute la section de la spécification, mais les phrases suivantes sont une bonne discussion sur le danger d'utiliser des références obsolètes:

  

Une référence vicié est une référence à un objet Java qui appartient   le chargeur de classe d'un paquet qui est arrêté ou est associé   avec un objet de service qui est non enregistrée. Java standard ne   fournir un moyen générique pour nettoyer les références obsolètes et bundle   les développeurs doivent analyser leur code avec soin pour faire en sorte que rassis   les références sont supprimés.

     

références Stale sont potentiellement dangereux, car ils entravent la Java   garbage collector de récolter les classes, et peut-être les cas,   des faisceaux arrêté. Cela peut entraîner une augmentation significative mémoire   l'utilisation et la mise à jour peut provoquer des bibliothèques de code natif à l'échec. Bundles utilisant   services est fortement recommandé d'utiliser le Tracker de service ou   Services déclaratifs.

Une référence de service ne doit jamais être conservé comme référence. Vous devriez toujours un service à l'exécution. Cela vous lie à l'api OSGI cependant whihc n'est pas toujours voulu.

Jetez un oeil à - OSGI ServiceTracker - OSGI services déclaratifs - OSGI BluePrint - Spring DM - Peaberry - iPOJO

qui sont tous prendre soin du dynamisme pour vous, la plupart d'entre eux sans api OSGI à utiliser.

Cordialement,

Leen Toelen

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top