2009-12-04 14 views
8

Une fois qu'une instance d'un service OSGi est extraite du contexte de l'ensemble, est-elle invalidée lorsque le service est arrêté? Mes tests initiaux montrent que l'instance de service peut être utilisée même après l'arrêt de l'ensemble de services, ce qui contredit ma compréhension de la nature dynamique de l'OSGi. Je suppose que cela se résume à ce que récupère réellement un service (via ServiceTracker) d'un autre paquet dans le conteneur OSGi, crée-t-il une nouvelle instance ou donne-t-il un pointeur sur l'instance enregistrée dans le conteneur ?Références de service dans OSGi

L'utilisation de l'instance de service présente-t-elle des risques lorsque le service a été arrêté?

Répondre

5

Ceci est une très bonne question, j'ai donc creusé dans la spécification à la recherche d'une réponse définitive. Il s'avère qu'il y a une section entière qui parle de ce problème - voir la section 5.4 Stale Références commençant à la page 132 de OSGi Service Platform Core Specification, Release 4, Version 4.2.

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

Le comportement d'un service qui devient non enregistrée est définie. De tels services peuvent continuer à fonctionner correctement ou émettre 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 références obsolètes.

La spécification donne également quelques conseils pour minimiser les conséquences des références périmées.

+0

Merci pour la réponse, malheureusement pas un oui définitif ou non comme je l'espérais! –

2

Vous avez raison car cela est en contradiction avec la nature dynamique d'OSGi. Je crois qu'il n'y a aucune garantie que le service sera disponible, bien que les 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é avec Spring DM, le service récupéré est en réalité un proxy Spring de l'implémentation sous-jacente et l'implémentation peut toujours disparaître. Ainsi, une référence de service qui se réfère directement à une implémentation peut empêcher cet objet d'être supprimé, contrairement à la référence basée sur un proxy.

1

La spécification OSGi dit:

Bundles sont des entités qui sont visibles dans programmation d'application normale. Pour par exemple, quand un groupe est arrêté, tous ses services seront désinscrits .

Vous ne devriez donc pas être en mesure d'obtenir un service d'un ensemble arrêté. Mais techniquement, il peut être possible de l'utiliser, au moins tant que vous détenez une référence à l'objet de service (personne ne peut vous l'enlever et il ne sera pas GC'd). Mais je ne pense pas que ce soit l'utilisation du service. Cela peut dépendre d'autres ressources d'ensemble, qui ne sont pas disponibles après l'arrêt de l'ensemble.

0

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

Le comportement d'un service qui devient non enregistrée est indéfini. De tels services peuvent continuer à fonctionner correctement ou émettre 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 rassis est une référence à Java objet qui appartient au chargeur de classe d'un ensemble arrêté ou associé à un objet de service non enregistré. Java standard ne fournit aucun moyen générique pour nettoyer les références périmées, et les développeurs bundle doivent analyser leur code avec soin pour s'assurer que références périmées sont supprimées.

Les références périmées sont potentiellement dangereuses car elles empêchent le garbage collector Java de récupérer les classes, et éventuellement les instances des groupes arrêtés. Cela peut entraîner une augmentation significative de l'utilisation de la mémoire et entraîner la défaillance de la mise à jour des bibliothèques de code natives. Les offres groupées utilisant les services sont fortement recommandées pour utiliser le Service Tracker ou les Services déclaratifs .

1

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

Non, la référence elle-même n'est pas invalidée. Tant que quelque chose se trouve dans le contenant, il ne peut pas non plus être GC.

Toutefois, qu'il soit toujours utile ou non, cela dépend uniquement de l'implémentation de service elle-même, pas du conteneur. Mes tests initiaux montrent que l'instance de service peut être utilisée même après l'arrêt du service bundle, ce qui contredit ma compréhension de la nature dynamique de l'OSGi. Les spécifications elles-mêmes indiquent que de telles références ne devraient pas être tenues, mais il appartient à l'exécutant de veiller à la mise en œuvre correcte des spécifications; signifie qu'il n'y a pas de contradiction, il y a seulement le fait que vous pouvez implémenter et déployer des bundles 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, elle 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 nouvelles instances de services, sauf s'il s'agit d'une ServiceFactory impliquée (voir les spécifications). Rechercher un service devrait toujours vous donner un pointeur vers l'instance enregistrée dans le conteneur.

Y a-t-il des dangers dans l'utilisation de l'instance de service après l'arrêt du service?

Cela dépend uniquement de l'implémentation du service; Cependant, en faisant cela dans un paquet, vous créez automatiquement un paquet qui n'est pas conforme aux spécifications.

En pratique, de nombreux services sont implémentés pour libérer des ressources et des références et ne répondront plus correctement.

0

Une référence de service ne doit jamais être conservée comme référence. Vous devriez toujours rechercher un service à l'exécution. Cela vous amène à l'API d'OSGI, ce qui n'est pas toujours le cas.

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

qui tout pour vous prendre en charge le dynamisme, la plupart d'entre eux sans OSGI api à utiliser.

Cordialement,

Leen Toelen