Quand dois-je utiliser Import-Package et quand dois-je utiliser Require-Bundle?

OSGi permet de déterminer les dépendances via Import-Package , qui ne fait que connecter un seul package (exporté depuis n’importe quel bundle) et Require-Bundle , qui se connecte aux exportations d’un bundle nommé spécifique.

En construisant une application OSGi, quelle approche dois-je utiliser pour représenter les dépendances? La plupart des bundles seront internes, mais il y aura des dépendances sur des bundles externes (open-source).

Je crois que Require-Bundle est une chose Eclipse (qui est maintenant dans la spécification OSGi pour s’adapter à Eclipse). La méthode OSGi “pure” consiste à utiliser Import-Package , car elle découplera spécifiquement le package du bundle qui le fournit. Vous devriez déclarer des dépendances sur les fonctionnalités dont vous avez besoin (l’API Java fournie par une certaine version d’un package donné) au lieu de savoir d’où vient cette fonctionnalité (ce qui ne devrait pas vous intéresser). Cela garde la composition des paquets plus flexible.

Analogie avec JavaScript: Cela revient à détecter si un navigateur Web prend en charge une certaine API et à déduire de ce que la chaîne de l’agent utilisateur indique comme type de navigateur.

Peter Kriens de l’OSGi Alliance a plus à dire à ce sujet sur le blog OSGi .

Le seul cas où vous devez utiliser Require-Bundle est probablement que si vous avez des packages divisés, il s’agit d’un package réparti sur plusieurs bundles. Les paquets fractionnés sont bien sûr fortement déconseillés.

Privilégiez le paquet d’importation sur le paquet Require.

Require-Bundle:

  • spécifie le bundle explicite (et la version) à utiliser. Si un ensemble de requêtes doit être refait et qu’un paquet est déplacé ailleurs, les personnes à charge auront besoin de modifier leur fichier MANIFEST.MF.
  • vous donne access à TOUTES les exportations du bundle, indépendamment de leur nature et indépendamment de votre besoin. Si les pièces dont vous n’avez pas besoin ont leurs propres dépendances, vous en aurez besoin pour
  • les paquets peuvent être réexportés
  • bien que déconseillé, permet l’utilisation de packages fractionnés, c’est-à-dire: un package réparti sur plusieurs bundles
  • peut être utilisé pour des dépendances sans code, par exemple: ressources, aide, etc.

Package d’importation:

  • couplage plus souple, seul le package (et la version) est spécifié et le run-time trouve le bundle requirejs
  • Les implémentations réelles peuvent être remplacées
  • Les packages dépendants peuvent être déplacés vers différents bundles par le propriétaire du package
  • Mais nécessite plus de métadonnées à maintenir (c.-à-d. Chaque nom de paquet) à des niveaux de granularité inférieurs

Je crois que Import-Package vous donne un couplage plus souple et devrait être préféré. Je l’utilise lors de la déclaration de dépendances sur des paquets que je ne possède pas, tels que slf4j, et je peux permuter les implémentations comme je le souhaite. J’utilise Require-Bundle lorsque la dépendance est quelque chose sur laquelle j’ai le contrôle, comme mes propres bundles, car de toute façon, tout changement important serait passé par moi-même.

Évitez le package d’importation. Comme les packages fournissent des relations plusieurs à plusieurs entre les bundles, ils sont sujets à des cycles de dépendance difficiles à détecter et à éviter.

Par contre, Require-Bundle fait référence à un seul bundle, ce qui rend le graphe de dépendance protégé des cycles par une vérification sortingviale au moment de la construction. Avec Require-Bundle, il est beaucoup plus facile de créer une architecture en couches avec un niveau d’abstraction inférieur isolé.

Import-Package doit être amélioré car, comme indiqué précédemment, vous pouvez déplacer un package d’un lot à un autre sans modifier le fichier MANIFEST.MF du client existant.

Mais…

Il y a une raison pratique d’utiliser Require-Bundle si vous utilisez Eclipse pour développer vos bundles:

Eclipse n’utilise pas les packages comme unités de résolution. Il utilise des bundles. En d’autres termes, si vous utilisez un paquet d’un ensemble, Eclipse comstack votre ensemble sans signaler aucun problème lié à l’utilisation du rest des paquets non importés de ce groupe.

Vous pourriez (vous êtes humain) penser que tout va bien et télécharger votre bundle pour le déploiement, mais … votre bundle sera cassé à l’exécution.

J’en suis sûr car ce problème est arrivé (à moi!) Aujourd’hui.

La bonne solution serait de changer le conteneur de classpath d’Eclipse mais … si cela ne va pas se faire … vous pourriez décider d’éviter ce genre de problèmes nécessitant des bundles, au lieu de packages, payant le prix mentionné (pas de compatibilité descendante). mouvement de code entre les paquets).

Je ne suis pas convaincu que l’utilisation d’Import-Package est meilleure, car mon attente par défaut lorsque je travaille avec un bundle est de travailler avec l’API publique associée. Pour cette raison, Require-Bundle a plus de sens.