employés 80% de business Java Contribution à des projets open-source 10% de la force de travail Membre de l’EG JSR-346 www.serli.com @SerliFr 5 5 jeudi 19 avril 12
employés 80% de business Java Contribution à des projets open-source 10% de la force de travail Membre de l’EG JSR-346 www.serli.com @SerliFr 5 5 jeudi 19 avril 12
vous montrer comment CDI a été mis en pratique à travers le fonctionnement du module Seam Social Vous verrez également comment CDI peut être modularisé grâce à Weld OSGI Nous profiterons également de ces 3 heures pour monter une petite application sociale en CDI et JSF / Primefaces et la même utilisant Twitter Bootstrap 7 7 jeudi 19 avril 12
EJB Container Managed Bean (POJO) Servlet 3.0 JSF 2.0 Client Tier Application Client Container Web Browser JTA JPA JMS JAX-WS JAX-RS Messaging SOA JCA JAXB JAAS CDI est une technologie d’intégration qui enrichi aussi bien des POJO que des EJB Il a vocation à servir de «glue» entre les différentes parties de la stack Java EE C’est la première technologie qui permet d’étendre Java EE de manière portable et naturelle CDI dans Java EE 10 jeudi 19 avril 12
l’utilisation des réseaux sociaux Inspiré par Spring Social, il propose un noyau très différent tirant parti des spécificités CDI Les binding des API des réseaux sociaux, en revanche sont pour l’instant des forks de ceux de Spring Social Connecteurs out of the box 11 11 jeudi 19 avril 12
JSON Jackson permet également de mapper du JSON sur des classes java Pour ça il peut utiliser des annotations JAXB ou ses propres annotations En plus Jackson propose la notion de Mixin qui permet de déporter les annotations sur une classe dédiée et de laisser la classe d’origine propre. 13 @JsonIgnoreProperties(ignoreUnknown = true) @SuppressWarnings("unused") abstract class TwitterProfileMixin { @JsonCreator TwitterProfileMixin(@JsonProperty("id") String id, @JsonProperty("screen_name") String screenName, @JsonProperty("name") String name, @JsonProperty("url") String url, @JsonProperty("profile_image_url") String profileImageUrl, @JsonProperty("description") String description, @JsonProperty("location") String location, @JsonProperty("created_at") @JsonDeserialize(using = TimelineDateDeserializer.class) Date createdDate) { } @JsonProperty("notifications") private boolean notificationsEnabled; @JsonProperty("lang") private String language; @JsonProperty("statuses_count") private int statusesCount; ... 13 jeudi 19 avril 12
veut binder, il faut créer une classe abstraite : un Mixin Ce mixin comporte les annotations Jackson qui seront utilisées pour associé le JSON au pojo Un module Jackson est nécessaire pour créer l’association 14 Texte Pojo PojoMixin Module Jackson 14 jeudi 19 avril 12
REST comme protocole d’échange Les données transmises sont au format JSON et certains proposent XML en option Enfin, la sécurisation (encryption et authentification) passe par le protocole OAuth. 16 jeudi 19 avril 12
l’utilisation d’un service donné (autoriser sans partager ses données d’accès avec l’entité à qui on délègue l’accès au service) Développé par Twitter, Magnolia puis Google, il est normalisé par l’IETF en avril 2010 via la RFC 5849 La version 2.0 plus simple d’utilisation est en cours de standardisation mais déjà utilisée par certains acteurs (Facebook, Google, Microsoft) Tous les Réseaux Sociaux s’appuient sur Oauth 1.0a ou 2.0 Pour utiliser OAuth on doit commencer par déclarer une application sur le service concerné. Celui-ci vous délivrera une Consumer_Key (clé asymétrique) 17 17 jeudi 19 avril 12
une ressource sur le service tiers Serveur de l’application Service tiers (OAuth) L’application demande un request Token (relatif à l’application déclarée) au service et envoie une url de callback à associer au token Client 18 jeudi 19 avril 12
demande une ressource sur le service tiers Serveur de l’application Service tiers (OAuth) Le service retourne le token L’application demande un request Token (relatif à l’application déclarée) au service et envoie une url de callback à associer au token Client 18 jeudi 19 avril 12
demande une ressource sur le service tiers Serveur de l’application Service tiers (OAuth) L’application redirige le client sur la page de login du service Le service retourne le token 4 L’application demande un request Token (relatif à l’application déclarée) au service et envoie une url de callback à associer au token Client 18 jeudi 19 avril 12
demande une ressource sur le service tiers Serveur de l’application Service tiers (OAuth) L’application redirige le client sur la page de login du service Le service retourne le token 4 5 L’application demande un request Token (relatif à l’application déclarée) au service et envoie une url de callback à associer au token Une fois connecté le service redirige le client vers l’URL de callback avec un code de vérification Client 18 jeudi 19 avril 12
demande une ressource sur le service tiers Serveur de l’application Service tiers (OAuth) L’application redirige le client sur la page de login du service Le service retourne le token 4 5 L’application demande un request Token (relatif à l’application déclarée) au service et envoie une url de callback à associer au token Une fois connecté le service redirige le client vers l’URL de callback avec un code de vérification 6 A l’aide du code et du Token, le service demande un Access Token Client 18 jeudi 19 avril 12
demande une ressource sur le service tiers Serveur de l’application Service tiers (OAuth) L’application redirige le client sur la page de login du service Le service retourne le token 4 5 L’application demande un request Token (relatif à l’application déclarée) au service et envoie une url de callback à associer au token Une fois connecté le service redirige le client vers l’URL de callback avec un code de vérification 6 A l’aide du code et du Token, le service demande un Access Token 7 Le service retourne l’access token Client 18 jeudi 19 avril 12
construire des API d’accès aux réseaux sociaux La connexion et l’identification sont génériques pour fournir un moyen standard de s’authentifier Découverte dynamique de nouveaux modules (le socle reconnait automatiquement un nouveau connecteur) Fourniture de services haut niveau (bindings et appels) vers les services en ligne 21 jeudi 19 avril 12
un nouveau réseau social) il faut : S’assurer que Scribe-Java propose un connecteur vers ce service ou créer ce connecteur (une classe) Etendre AbstractSocialNetworkService pour fournir le socle aux API du service Créer un Qualifier (annotation) portant la meta annotation @ServiceRelated Implementer SocialNetworkService Hub pour les services génériques. Il ne reste plus qu’à coder les bindings JSON et API. 24 jeudi 19 avril 12
cool) #annotationsEverywhere #noXml Typesafe Aucune limite à ce que vous pouvez faire avec CDI Si vous pouvez l’imaginer, vous pouvez le faire Extensions portables standard :-) JBoss Weld en est l’implémentation de référence plutôt mature, très bonne communauté Deux autres implémentations : Apache Open WebBeans Caucho Candi Limité à Java EE 6 ? et bien, pas forcément ... 27 27 jeudi 19 avril 12
simplement en dehors de Java EE 6 à priori, vous pouvez le bootstraper n’importe où :-) Weld-Servlet Jetty Tomcat 6/7 Weld-SE Bonne vieilles applications desktop 28 28 jeudi 19 avril 12
hello(); } public class FrenchHelloService implements HelloService { public String hello() { return "Bonjour tout le monde!"; } } public class EnglishHelloService implements HelloService { public String hello() { return "Hello World!"; } } 37 jeudi 19 avril 12
public String hello() { return "Bonjour tout le monde!"; } } @English public class EnglishHelloService implements HelloService{ public String hello() { return "Hello World!"; } } 41 jeudi 19 avril 12
public String hello() { return "Bonjour tout le monde!"; } } @Language(ENGLISH) public class EnglishHelloService implements HelloService { public String hello() { return "Hello World!"; } } 43 jeudi 19 avril 12
du moment de la création et de la destruction des beans ‘un singleton pour un contexte donné’ Contexte requête, session, conversation, application, singleton Possibilité de créer des scopes personnalisés via les extensions 52 52 jeudi 19 avril 12
De créer des Beans (fichier de configuration) ou des points d’injection modifier des beans ou des points d’injection Annuler la création de beans D’une manière générale inventorier l’ensembles de l'écosystème CDI de l’application, le modifier ou l’enrichir. 68 68 jeudi 19 avril 12
BeanManager est en lecture seule (pas de création de Bean au runtime) Ne pas confondre Bean (définition) avec Instance de Bean Nos extensions seront donc exécutées au démarrage de l’application et devront influer sur le contenu du BeanManager et des futurs beans Les extensions peuvent aussi devenir des Beans (avec quelques restrictions) 69 jeudi 19 avril 12
Process Producers Process Anotated Types Scan Archive Application Running After Deployment Validation Before Shutdown Undeploy Application Process Beans After Bean Discovery Process Injection Taget Process Observer Methods 70 jeudi 19 avril 12
implémente Extension avec un constructeur sans paramètres Y placer une ou plusieurs méthodes avec un observer sur les événements du cycle de vie CDI pour intervenir sur le contenu du bean manager Ajouter dans le classpath le fichier META-INF/services/javax.enterprise.inject.spi.Extension dans lequel on ajoutera le nom qualifié de la classe d’extension 71 jeudi 19 avril 12
pat, BeanManager beanManager) { final AnnotatedType<X> annotatedType = pat.getAnnotatedType(); final Class<X> javaClass = annotatedType.getJavaClass(); final Package pkg = javaClass.getPackage(); // Support for @Veto if (annotatedType.isAnnotationPresent(Veto.class) || (pkg != null && pkg.isAnnotationPresent(Veto.class))) { pat.veto(); log.info("Preventing " + javaClass + " from being installed as bean due to @Veto annotation"); return; } } 72 jeudi 19 avril 12
pat, BeanManager beanManager) { final AnnotatedType<X> annotatedType = pat.getAnnotatedType(); final Class<X> javaClass = annotatedType.getJavaClass(); final Package pkg = javaClass.getPackage(); // Support for @Veto if (annotatedType.isAnnotationPresent(Veto.class) || (pkg != null && pkg.isAnnotationPresent(Veto.class))) { pat.veto(); log.info("Preventing " + javaClass + " from being installed as bean due to @Veto annotation"); return; } } 72 jeudi 19 avril 12
source Et nous comptons sur vous pour créer des modules Seulement ajouter un module nécessite de redéployer l’application Comment faire pour charger un module à chaud ? OSGi arrive à la rescousse pour résoudre ce problème 74 jeudi 19 avril 12
utilisation d’annotations, etc ... Extension CDI permettant d’utiliser le modèle de programmation CDI dans OSGi Pas besoin de connaître OSGi faire disparaitre le modèle de programmation OSGi en faveur de celui de CDI modèle de programmation standard ... mais reste compatible 81 81 jeudi 19 avril 12
un environnement OSGi expérimentations à faire sur la compatibilité des modèles de programmation Développé par l’équipe R&D SERLI Mathieu ANCELIN & Matthieu CLOCHARD 82 82 jeudi 19 avril 12
cible (twitter, facebook, etc ...) ajout de quelques classes pour permettre l’intégration via Weld-OSGi aucun export de package nécessaire nous allons exposer un service via un type de l’API commune import des packages des librairies utilisées ainsi que de l’API commune 91 91 jeudi 19 avril 12
un Service type ‘SocialProvider’ à travers le registre de services OSGi à disposition des autres bundles Weld-OSGi à disposition des autres bundles OSGi utilisable par d’autres applications 92 92 jeudi 19 avril 12
service OSGi permettant d’accéder au Posts qu’il manipule ‘Socializer’ doit consommer ces Posts pour les afficher dans son interface différentes méthodes possibles privilégions une approche générique 95 95 jeudi 19 avril 12
SocialProvider provider’ n’existe pas dans l’application cliente Au démarrage de l’extension CDI, Weld-OSGi va scanner tous les points d’injection recherche tous les PI utilisant @OSGiService et créé des beans correspondant cependant n’écrase pas les beans existant pour que l’application continue à fonctionner comme doit, tout n’est pas censé être OSGi-ifié 97 97 jeudi 19 avril 12
échoue si aucun service disponible 98 @Inject @OSGiService MyService service; Provider InjectionPoint create() Le rôle de l’extension 98 jeudi 19 avril 12
échoue si aucun service disponible 98 @Inject @OSGiService MyService service; P R O X Y Provider InjectionPoint create() get() Le rôle de l’extension 98 jeudi 19 avril 12
échoue si aucun service disponible 98 @Inject @OSGiService MyService service; P R O X Y Provider InjectionPoint create() get() Le rôle de l’extension Extension CDI 98 jeudi 19 avril 12
for (SocialProvider provider : providers.first()) { provider.getTimeline(); // appel sur 0-1 service } for (SocialProvider provider : providers) { provider.getTimeline(); // appel sur 0-n service(s) } providers.get().getTimeline(); // peut échoué car non dynamique providers.size(); providers.isUnsatisfied(); providers.isAmbiguous(); 100 Injection de services 100 jeudi 19 avril 12
@Inject @Filter("(twitter=true)") Service<SocialProvider> service; @Inject @OSGiService @Twitter SocialProvider service; 105 Et si on souhaite un service en particuliers ? 105 jeudi 19 avril 12
@Inject @Filter("(twitter=true)") Service<SocialProvider> service; @Inject @Twitter Service<SocialProvider> service; 106 Et si on souhaite un service en particuliers ? 106 jeudi 19 avril 12
mais parfois il est absolument nécessaire d’avoir un certain service pour que tout fonctionne Weld-OSGi vous prévient lorsque des services requis sont disponibles peut fonctionner de manière globale pour tous les services requis du bundle peut cibler des services requis en particulier 107 107 jeudi 19 avril 12
désenregistrements de services enregistrement d’un service requis Bean B Bean A 108 Des services requis ... notifications Extension CDI 108 jeudi 19 avril 12
désenregistrements de services enregistrement d’un service requis évènements de validation des dépendances Bean B Bean A 108 Des services requis ... notifications Extension CDI 108 jeudi 19 avril 12
désenregistrements de services enregistrement d’un service requis évènements de validation des dépendances Bean B Bean A 108 Des services requis ... notifications Extension CDI 108 jeudi 19 avril 12
interagir avec les couches bundle et services meilleur moyen de gérer le côté dynamique du framework Evènements disponibles : bundle events service events 114 114 jeudi 19 avril 12
lorsqu’un nouveau service est disponible géré de manière asynchrone, pas besoin de vérifier ‘à la main’ permet d’afficher une notification à l’utilisateur lui demandant de se connecter utilisation des servlets asynchrones ? 115 115 jeudi 19 avril 12
depuis un EJB avec @Schedule Récupération des timelines de manière asynchrone Mise en cache pour des raisons de performances Envoi des nouveaux ‘Post’ vers l’application cliente pour une mise à jour en temps réel 127 jeudi 19 avril 12
Plugin Forge CDI Extension pour les serveurs Java EE hybrides utiliser Weld-OSGi dans une application Java EE en cours ;-) Intégration avec les spécifications entreprise une future spécification OSGi entreprise ? 135 135 jeudi 19 avril 12
github : http://github.com/seam/social Si vous êtes intéressés par Socializer (branche Twitter Bootstrap incluse) : https://github.com/antoinesd/Socializer Seam Social dépasse le simple cadre d’un module CDI Une tentative de JSR a été conduite mais rejetée Un projet « Java Social » est en cours de constitution Une communauté s’est constituée. Pour ceux que ça intéresse suivez @antoine_sd ou @Java_social 137 137 jeudi 19 avril 12
est beaucoup plus sympathique que vous ne le pensez Surtout avec Weld-OSGi Seam Social c’est cool mais le sera encore plus avec vous comme contributeur. 138 138 jeudi 19 avril 12