mercredi 13 août 2014

CDI 1.2 et le scope @javax.inject.Singleton, le mal aimé...

Si vous utilisez CDI a.k.a. Contexts and Dependency Injection for the Java EE Platform, peut-être utilisez-vous aussi CDI dans un contexte Java SE, i.e. en dehors de tout serveur d’application Java EE.
Le 8 avril 2014 a vu le jour d’une maintenance release pour CDI à savoir la version 1.2.
Cette version n’est actuellement pas fournie par un serveur d’application quelconque, la spécification Java EE 7 s’appuyant sur CDI 1.1 et Java EE 8 devrait quant-à elle s’appuyer sur CDI 2.0.


CDI 1.2


La documentation de cette nouvelle mouture est disponible à l’URL suivante sur le site de JBoss.
L’objectif premier de cette version est de clarifier certains éléments de la spécification comme le fonctionnement des événements liés au cycle de vie du conteneur. Toutefois, bien que cette version ne semble être qu’intermédiaire, les travaux menés peuvent parfois être déroutant pour ceux qui utilisent le scope @javax.inject.Singleton à ne pas confondre avec l’annotation @javax.ejb.Singleton propre à la spécification EJB 3.1 et +
Et c’est là justement que les choses peuvent déranger car dorénavant, la spécification CDI 1.2, lorsqu’elle adresse des questions liés à des beans @Singleton, il n’est question exclusivement que des beans Singletons EJB !
Ok ! Peut-être que la stratégie à long terme est de ne disposer que d’une seule annotation @Singleton plutôt que d’avoir deux annotations, la première dans le package javax.inject et la deuxième dans javax.ejb.


Le Singleton : mal aimé du monde Java SE ?


La question est volontairement un peu provocatrice mais le problème constaté est que dorénavant, tous les beans annotés avec l’annotation @javax.inject.Singleton ne sont plus systèmatiquement chargés par CDI dès lors que le fichier "beans.xml" est présent et que le mode "bean-discovery-mode" est positionné à "annotated".

Dans ce cas, vous avez le droit à une belle IllegalStateException :






Bref, si vous vous retrouvez dans cette situation, il faut alors recréer sa propre annotation, par exemple @Unique (ou appelez-là comme vous voulez) en la faisant hériter de @Stereotype et @javax.inject.Singleton :











Vous trouverez plus d'explications, une implémentation et quelques tests unitaires sur mon GitHub ou en accédant à la documentation générée à partir du plugin Maven Site 3.3.

J'espère qu'il y aura une forme d'alignement quelconque entre CDI et l'annotation @javax.inject.Singleton d'ici la version 2.0 de la spéc :)