2009-08-23 5 views
2

Je travaille dans un environnement Java EE dans lequel chaque application est dans son propre fichier de guerre. Dans le fichier WEB-INF/lib de chaque fichier WAR d'application, un fichier JAR commun est partagé par toutes les applications. Ce pot commun contient plusieurs singletons auxquels on accède à partir de nombreux points du code. En raison des limites du fichier de guerre, chaque application a ses propres instances des singletons. C'est ainsi que nous fonctionnons aujourd'hui, puisque nous voulons configurer certains singletons différemment dans chaque application. Maintenant nous nous dirigeons vers un environnement OSGi, où cette solution ne fonctionnera plus puisque chaque paquet a son propre chargeur de classe, donc si j'essaie d'accéder à MySingleton qui réside dans le paquet "common.jar" du paquet "appA. jar "ou du paquet" appB.jar "je vais avoir la même instance. Rappelez-vous que je "veux" une instance différente d'un singleton par bundle. (aussi ironique que cela puisse paraître)Solution de migration pour les singletons dans un environnement OSGI

Maintenant, je réalise que la solution idéale serait de corriger le code pour ne pas compter sur ces singletons, mais en raison d'un calendrier serré, je me demandais si vous pouviez suggérer une sorte de solution de migration cela me permettrait d'utiliser des singletons à l'échelle du paquet afin que chacun d'entre eux puisse être configuré par paquet.

Répondre

1

je peux penser à quelques options:

  1. Joignez une copie de toutes les classes common.jar directement dans le faisceau de WAR.
  2. Nest common.jar dans chaque paquet WAR, puis modifier le chemin de classe de paquet dans MANIFEST.MF pour inclure le pot imbriqué: Bundle-Classpath:., Common.jar
  3. Modifier le singleton à utiliser les services OSGi, et l'utilisation un ServiceFactory pour s'assurer que chaque groupe demandeur reçoit sa propre instance de ce service. Vous devrez mettre en cache l'instance de service (ne pas obtenir/utiliser/unget) pour éviter d'avoir une nouvelle instance sur chaque accès.
+0

En ce qui concerne l'option 2, OSGi fonctionne-t-il avec les fichiers war? Je pensais que les bundles OSGi sont simplement des fichiers jar. –

+0

Il n'y a rien dans la spécification OSGi qui limite un ensemble à une instance d'un fichier JAR. Voir Spring DM et OPS4J pour des exemples de support WAR. – SteveD

2

Votre singleton sera un service dans OSGi.

Ensuite, vous devez créer une ManagedServiceFactory (voir par exemple ce article) responsable de l'enregistrement de différentes instances de ce service; chaque service sera enregistré avec des propriétés différentes (f.i. application = "appA" et application = "appB")

Après cela, vous accéderez au bon service à partir de n'importe quelle application effectuant une recherche de service normal spécifiant les propriétés correctes.

+1

Ou piratez le getter du singleton pour prendre une clé arbitraire (comme le contexte du bundle) qui vous permet de renvoyer un singleton par clé. – SteveD

1

Les singletons correspondent en effet aux services. Si les applications (appA, appB) sont en réalité des bundles, alors implémentez votre service en tant que ServiceFactory. Cela vous permettra de renvoyer automatiquement une instance distincte pour chaque ensemble d'appels. Ce sera plus facile qu'une ManagedServiceFactory (qui a besoin d'une configuration explicite pour chaque instance) ou des getters de piratage.

Questions connexes