Développons en Java 2.30 | |
Copyright (C) 1999-2022 Jean-Michel DOUDOUX | (date de publication : 15/06/2022) |
|
Niveau : | Supérieur |
J2EE est l'acronyme de Java 2 Entreprise Edition. Cette édition est dédiée à la réalisation d'applications pour entreprises. J2EE est basé sur J2SE (Java 2 Standard Edition) qui contient les API de base de Java. Depuis sa version 5, J2EE est renommée Java EE (Enterprise Edition).
Ce chapitre contient plusieurs sections :
J2EE est une plate-forme fortement orientée serveur pour le développement et l'exécution d'applications distribuées. Elle est composée de deux parties essentielles :
Sun propose une implémentation minimale des spécifications de J2EE : le J2EE SDK. Cette implémentation permet de développer des applications respectant les spécifications mais n'est pas prévue pour être utilisée dans un environnement de production. Ces spécifications doivent être respectées par les outils développés par des éditeurs tiers.
L'utilisation de J2EE pour développer et exécuter une application offre plusieurs avantages :
J2EE permet une grande flexibilité dans le choix de l'architecture de l'application en combinant les différents composants. Ce choix dépend des besoins auxquels doit répondre l'application mais aussi des compétences dans les différentes API de J2EE. L'architecture d'une application se découpe idéalement en au moins trois tiers :
|
La suite de ce chapitre sera développée dans une version future de ce document
|
J2EE / Java EE regroupe un ensemble d'API pour le développement d'applications d'entreprise.
API | Rôle | version de l'API dans J2EE/Java EE |
||||||
1.2 |
1.3 |
1.4 |
5 |
6 |
7 |
8 |
||
Entreprise Java Bean (EJB) | Composants serveurs contenant la logique métier |
1.1 |
2.0 |
2.1 |
3.0 |
3.1 |
3.2 |
3.2 |
Remote Method Invocation (RMI) et RMI-IIOP | RMI permet l'utilisation d'objets Java distribués. RMI-IIOP est une extension de RMI pour une utilisation avec CORBA. |
1.0 |
|
|||||
Java Naming and Directory Interface (JNDI) | Accès aux services de nommage et aux annuaires d'entreprises |
1.2 |
1.2 |
1.2.1 |
||||
Java Database Connectivity (JDBC) | Accès aux bases de données. J2EE intègre une extension de cette API |
2.0 |
2.0 |
3.0 |
||||
Java Transaction API (JTA) Java Transaction Service (JTS) |
Support des transactions |
1.0 |
1.0 |
1.0 |
1.1 |
1.1 |
1.2 |
1.2 |
Java Message service (JMS) | Support de messages avec des MOM (Messages Oriented Middleware) |
1.0 |
1.0 |
1.1 |
1.1 |
1.1 |
2.0 |
2.0 |
Servlets | Composants basés sur le concept C/S pour ajouter des fonctionnalités à un serveur. Pour le moment, principalement utilisé pour étendre un serveur web |
2.2 |
2.3 |
2.4 |
2.5 |
3.0 |
3.1 |
4.0 |
Java Server Pages (JSP) |
1.1 |
1.2 |
2.0 |
2.1 |
2.2 |
2.3 |
2.3 |
|
Java Server Faces (JSF) | 1.2 |
2.0 |
2.2 |
2.3 |
||||
Expression Language (EL) | 2.2 |
3.0 |
3.0 |
|||||
Java Server Pages Standard Tag Libray (JSTL) | 1.2 |
1.2 |
1.2 |
1.2 |
||||
JavaMail | Envoi et réception d'e-mails |
1.1 |
1.2 |
1.3 |
1.4 |
1.4 |
1.4 |
1.6 |
J2EE Connector Architecture (JCA) | Connecteurs pour accéder à des ressources du système d'information de l'entreprise telles que CICS, TUXEDO, SAP ... |
|
1.0 |
1.5 |
1.5 |
1.6 |
1.6 |
1.7 |
Java API for XML Parsing (JAXP) | Analyse et exploitation de données au format XML |
|
1.1 |
1.2 |
||||
Java Authentication and Authorization Service (JAAS) | Echange sécurisé de données |
|
1.0 |
|||||
JavaBeans Activation Framework | Utilisé par JavaMail : permet de déterminer le type MIME |
|
1.0.2 |
1.0.2 |
||||
Java API for XML-based RPC (JAXP-RPC) | 1.1 |
1.1 |
1.1 |
1.1 |
1.1 |
|||
SOAP with Attachments API for Java (SAAJ) | 1.2 |
1.3 |
||||||
Java API for XML Registries (JAXR) | 1.0 |
1.0 |
1.0 |
1.0 |
1.0 |
|||
Java Management Extensions (JMX) | 1.2 |
|||||||
Java Authorization Service Provider Contract for Containers (JACC) | 1.0 |
1.1 |
1.4 |
1.4 |
1.5 |
|||
Java API for XML-Based Web Services (JAX-WS) | 2.0 |
2.2 |
2.2 |
2.2 |
||||
Java Architecture for XML Binding (JAXB) | 2.0 |
2.2 |
||||||
Streaming API for XML (StAX) | 1.0 |
|||||||
Java Persistence API (JPA) | 1.0 |
2.0 |
2.1 |
2.2 |
||||
Java API for RESTful Web Services (JAX-RS) | 1.1 |
2.0 |
2.1 |
|||||
Web Services | 1.2 |
1.3 |
1.3 |
1.3 |
||||
Web Services Metadata for the Java Platform | 2.1 |
2.1 |
2.1 |
|||||
Java APIs for XML Messaging (JAXM) | 1.3 |
|||||||
Context and Dependency Injection (CDI) | 1.0 |
1.1 |
1.1 |
|||||
Dependancy Injection (DI) | 1.0 |
1.0 |
1.0 |
|||||
Bean Validation | 1.0 |
1.1 |
2.0 |
|||||
Managed beans | 1.0 |
1.0 |
1.0 |
|||||
Interceptors | 1.1 |
1.2 |
1.2 |
|||||
Common Annotations | 1.1 |
1.2 |
1.3 |
|||||
Java API for WebSocket |
1.0 |
1.1 |
||||||
Java API for JSON Processing (JSON-P) | 1.0 |
1.1 |
||||||
Concurrency Utilities for Java EE | 1.0 |
1.0 |
||||||
Batch Applications for the Java Platform | 1.0 |
1.0 |
||||||
Java API for JSON Binding (JSON-B) | 1.0 |
Ces API peuvent être regroupées en trois grandes catégories :
J2EE propose des spécifications pour une infrastructure dans laquelle s'exécutent les composants. Ces spécifications décrivent les rôles de chaque élément et précisent un ensemble d'interfaces pour permettre à chacun de ces éléments de communiquer.
Ceci permet de séparer les applications et l'environnement dans lequel elles s'exécutent. Les spécifications précisent à l'aide des API un certain nombre de fonctionnalités que doit implémenter l'environnement d'exécution. Ces fonctionnalités permettent aux développeurs de se concentrer sur la logique métier.
Pour exécuter ces composants de natures différentes, J2EE définit des conteneurs pour chacun d'eux. Il définit pour chaque composant des interfaces qui leur permettront de dialoguer avec les composants lors de leur exécution. Les conteneurs permettent aux applications d'accéder aux ressources et aux services en utilisant les API.
Les appels aux composants se font par des clients en passant par les conteneurs. Les clients n'accèdent pas directement aux composants mais sollicitent le conteneur pour les utiliser.
Les conteneurs assurent la gestion du cycle de vie des composants qui s'exécutent en eux. Les conteneurs fournissent des services qui peuvent être utilisés par les applications lors de leur exécution.
Il existe plusieurs conteneurs définis par J2EE:
Les serveurs d'applications peuvent fournir un conteneur web uniquement (exemple : Tomcat) ou un conteneur d'EJB uniquement (exemple : JBoss, Jonas, ...) ou les deux (exemple : Websphere, Weblogic, ...).
Pour déployer une application dans un conteneur, il faut lui fournir deux éléments :
Il existe trois types d'archives :
Archive / module | Contenu |
Extension
|
Descripteur de déploiement
|
bibliothèque | Regroupe des classes | jar |
|
application client | Regroupe les ressources nécessaires à leur exécution (classes, bibliothèques, images, ...) |
jar
|
application-client.jar
|
web | Regroupe les servlets et les JSP ainsi que les ressources nécessaires à leur exécution (classes, bibliothèques de balises, images, ...) |
war
|
web.xml
|
EJB | Regroupe les EJB et leurs composants (classes) |
jar
|
ejb-jar.xml
|
Une application est un regroupement d'un ou plusieurs modules dans un fichier EAR (Entreprise ARchive). L'application est décrite dans un fichier application.xml lui-même contenu dans le fichier EAR
Le conteneur web est une implémentation des spécifications servlets et par extension des spécifications des JSP. Ce type de conteneur est composé de deux éléments majeurs : un moteur de servlets (servlet engine) et un moteur de JSP (JSP engine).
Les conteneurs web peuvent généralement utiliser leur propre serveur web et être utilisés en tant que plug-in d'un serveur web dédié (Apache, IIS, ...).
L'implémentation de référence pour ce type de conteneur est le projet open source Tomcat du groupe Apache.
Les API spécifiquement mises en oeuvre dans un conteur web sont détaillées dans les chapitres «Les servlets»" et "JSP".
Les EJB sont détaillées dans le chapitre «Les EJB (Entreprise Java Bean)».
Une plate-forme d'exécution J2EE complète implémentée dans un serveur d'applications propose les services suivants :
Ces services sont utilisés directement ou indirectement par les conteneurs mais aussi par les composants qui s'exécutent dans les conteneurs grâce à leurs API respectives.
J2EE propose une spécification pour décrire le mode d'assemblage et de déploiement d'une application J2EE.
Une application J2EE peut regrouper différents modules : modules web, modules EJB ... Chacun de ces modules possède son propre mode de packaging. J2EE propose de regrouper ces différents modules dans un module unique sous la forme d'un fichier EAR (Entreprise ARchive).
Le format de cette archive est très semblable à celui des autres archives :
Les serveurs d'applications extraient chaque module du fichier EAR et les déploient séparément un par un.
Le fichier EAR est composé au minimum :
Les modules ne doivent pas obligatoirement être insérés à la racine du fichier EAR : ils peuvent être mis dans un des sous-répertoires pour organiser le contenu de l'application. Il est par exemple pratique de créer un répertoire lib qui contient les fichiers .jar des bibliothèques communes aux différents modules.
Pour créer un fichier EAR, il est possible d'utiliser un outil graphique fourni par le vendeur du serveur d'applications ou de créer le fichier manuellement en suivant les étapes indiquées ci-dessous :
Actuellement les fichiers EAR ne servent qu'à regrouper différents modules pour former une seule entité. Rien n'est actuellement prévu pour prendre en compte la configuration des objets permettant l'accès aux ressources par l'application telle qu'une base de données (JDBC pour DataSource, pool de connexions ...), un système de messages (JMS), etc ...
Pour pallier une partie de ces limites, les serveurs d'applications commerciaux proposent souvent des mécanismes propriétaires supplémentaires en attendant une évolution des spécifications.
La version 1.4 de J2EE a été diffusée en novembre 2003.
La grande nouveauté de la version 1.4 est le support des services web. Deux nouvelles API ont été ajoutées pour normaliser le déploiement (J2EE deployment API 1.1) et la gestion des applications (J2EE management API 1.0 qui utilise JMX). Une nouvelle API permet de standardiser l'authentification (Java ACC : Java Authorization Contract for Container). Plusieurs API déjà présentes dans les précédentes versions de J2EE ont été mises à jour (EJB, JSP, Servlet, ...) :
Le J2EE SDK 1.4 qui est l'implémentation de référence inclus le J2SE SDK 1.4.2 et J2EE 1.4 application server.
Le J2EE SDK 1.4 peut être installé sur les systèmes Microsoft suivants : Windows 2000 pro avec un service pack SP2, Windows XP Pro avec un service pack SP1 et Windows Server 2003.
Il existe plusieurs packages d'installation : celui utilisé ci-dessous ne contient que le serveur d'applications puisque le J2SE 1.4.2 était déjà présent sur la machine.
Lancer le programme j2eesdk-1_4-dr-windows-eval-app.exe. L'application extrait les fichiers, lance le J2RE et exécute un assistant qui va guider l'installation :
Cliquez sur « Create directory »
Il faut saisir des paramètres de configuration : saisir le mot de passe de l'administrateur et sélectionner l'option pour l'authentification ou non lors d'actions d'administration.
Il est aussi possible de définir les ports pour le module d'administration et pour les serveurs web HTTP et HTTPS.
Une fois les informations saisies, cliquez sur le bouton « Next ».
Il est utile de rajouter le répertoire bin du répertoire d'installation de J2EE SDK 1.4 à la variable PATH du système d'exploitation.
Un domaine permet de regrouper des applications qui s'exécutent avec une configuration particulière sur une instance donnée du serveur. Lors de l'installation un domaine par défaut est créé : domain1
Le programme d'installation a créé plusieurs entrées dans le menu « Démarrer/Programmes/Sun Microsystems/J2EE 1.4 SDK/ »
L'option « Start default domain » permet de démarrer le domaine domain1.
Il suffit d'appuyer sur une touche pour fermer la fenêtre.
Pour vérifier la bonne exécution du serveur, il suffit d'appeler l'URL http://localhost:nnnn/ dans un navigateur où nnnn représente le port http précisé dans les paramètres lors de l'installation.
L'arrêt du domaine par défaut peut être obtenu en utilisant l'option « Stop default domain ».
J2EE application server est livré avec une application nommée asadmin, utilisable sur une ligne de commandes, pour administrer le serveur.
Cette application utilise deux modes de fonctionnement :
Les commandes possèdent des noms bien définis en fonction de leurs actions et nécessitent souvent un ou plusieurs paramètres.
Exemple : démarrage d'un domaine
C:\>asadmin start-domain domain1
Starting Domain domain1, please wait.
Log redirected to C:\Sun\AppServer\domains\domain1\logs\server.log.
Domain domain1 started.
Exemple : arrêt d'un domaine
C:\>asadmin stop-domain domain1
Domain domain1 stopped.
Pour déployer une application sous la forme d'un fichier war ou ear il suffit de copier le fichier dans le sous-répertoire domains/nom_du_domaine/autodeploy.
Il est nécessaire de s'authentifier auprès du serveur d'applications pour certaines opérations.
La console d'administration est une application web qui permet de configurer le serveur.
Pour l'utiliser, le serveur doit être lancé et il suffit de saisir dans un navigateur l'URL http://localhost:4848/asadmin
Le nom de la cinquième version de la plate-forme Java pour Entreprise a été simplifié : au lieu de se nommer J2EE (Java 2 Enterprise Edition) version 1.5, la plate-forme a été renommée Java EE 5 (Java Enterprise Edition).
L'accent est mis dans cette version sur la simplification des développements tout en conservant et en faisant évoluer les fonctionnalités proposées par la plate-forme J2EE.
J2EE est réputée pour sa complexité et pour certaines lourdeurs essentiellement liées aux nombreuses entités à développer (classes, interfaces, fichiers de configuration, ...). La version 5 de la plate-forme repose sur la version 5 de la plate-forme Java Standard Edition et profite donc de ses améliorations notamment les generics et les annotations. L'utilisation intensive de ces dernières dans la version 5 de la plate-forme Java EE permet de simplifier les développements et ainsi de réduire le temps nécessaire à leur réalisation.
L'un des principaux buts de Java EE 5 est de conserver les fonctionnalités et la puissance de la plate-forme tout en simplifiant grandement le code à produire. Cette simplification repose essentiellement sur :
La simplification concerne aussi des sujets plus précis tels que l'utilisation des POJO ou l'injection de ressources.
Cette nouvelle version de la plate-forme, spécifiée dans la JSR 244, propose donc d'énormes simplifications dans le code à écrire par les développeurs.
Elle intègre aussi de nouvelles API :
Elle intègre aussi les dernières versions de la plupart des API qui formaient la version précédente de la plate-forme. Ainsi la version 5 de l'édition Entreprise de Java inclut de nombreuses spécifications :
Technologies pour les services web | |
Implementing Enterprise Web Services | JSR 109 |
Java API for XML-Based Web Services (JAX-WS) 2.0 | JSR 224 |
Java API for XML-Based RPC (JAX-RPC) 1.1 | JSR 101 |
Java Architecture for XML Binding (JAXB) 2.0 | JSR 222 |
SOAP with Attachments API for Java (SAAJ) | JSR 67 |
Web Service Metadata for the Java Platform | JSR 181 |
Technologies pour les composants | |
Enterprise JavaBeans 3.0 | JSR 220 |
J2EE Connector Architecture 1.5 | JSR 112 |
Java Servlet 2.5 | JSR 154 |
JavaServer Faces 1.2 | JSR 252 |
JavaServer Pages 2.1 | JSR 245 |
JavaServer Pages Standard Tag Library | JSR 52 |
Technologies de gestion et déploiement | |
J2EE Management | JSR 77 |
J2EE Application Deployment | JSR 88 |
Java Authorization Contract for Containers | JSR 115 |
Autres technologies | |
Common Annotations for the Java Platform | JSR 250 |
Java Transaction API (JTA) | JSR 907 |
JavaBeans Activation Framework (JAF) 1.1 | JSR 925 |
JavaMail | JSR 919 |
Streaming API for XML (StAX) 1.0 | JSR 173 |
La version 5 de la plate-forme Java EE fait un usage important des annotations introduites dans la plate-forme Java SE 5.0. Les annotations sont des métadonnées qui seront utilisées par le conteneur. Le code à écrire est ainsi réduit car certaines entités à définir ou règles à respecter sont simplement remplacées par l'utilisation d'une ou plusieurs annotations.
Historiquement, des tags étaient déjà utilisés notamment par Javadoc.
Une annotation commence par le caractère @ suivi par le nom de l'annotation éventuellement suivi d'une liste, entourée de parenthèses, de paramètres sous la forme de paires clé/valeur.
Les annotations précèdent par convention les modificateurs des entités qu'elles caractérisent. Elles correspondent à des classes particulières.
Les annotations n'ont aucune influence sur la logique des traitements du code mais elles influent sur la façon dont certains outils vont exécuter le code.
Java EE 5 propose des annotations pour de nombreux rôles :
L'utilisation des annotations n'est pas obligatoire : la configuration peut aussi être faite dans un descripteur de déploiement.
Le packaging a aussi été simplifié : il est maintenant possible d'écrire des EJB ou des services web sans devoir écrire de descripteur de déploiement sauf pour des besoins particuliers. La configuration est déduite par le conteneur à partir des annotations.
De nombreux attributs d'annotations possèdent des valeurs par défaut que le développeur pourra utiliser sans avoir à les préciser.
La version 3.0 des EJB propose une simplification de leur développement. Le travail des développeurs est réduit au profit d'une augmentation des traitements pris en charge par le conteneur :
Dans les versions antérieures des spécifications, les interactions entre le bean et le conteneur pour la gestion de son cycle de vie étaient réalisées par les méthodes ejbRemove(), setMessage(), setSessionContext(), ejbActivate() et ejbPassivate() des classes javax.ejb.SessionBean et javax.ejb.MessageDrivenBean. Même inutiles, ces méthodes devaient être écrites.
Dans la version 3.0, il suffit simplement d'utiliser les annotations définies dans les spécifications de Java EE dont voici les principales :
tag | Rôle |
@Stateless | annote une classe qui est un composant de type EJB Session Stateless |
@Stateful | annote une classe qui est un composant de type EJB Session Stateful |
@PostConstruct | |
@PreDestroy | |
@PostActivate | |
@PrePassivate | |
@EJB | annote un EJB qui sera injecté par le conteneur |
@WebServiceRef | annote un service web qui sera injecté par le conteneur |
@Resource | annote une ressource différente d'un EJB ou d'un service web qui sera injectée par le conteneur |
@MessageDriven | annote une classe qui est un composant de type EJB Message Driven |
@TransactionAttribute | annote une classe (dans ce cas toutes ses méthodes) ou une méthode pour préciser les attributs d'appartenance à une transaction |
@TransactionManagement | |
@RolesAllowed, @PermitAll @DenyAll |
annote une méthode pour indiquer ses permissions d'utilisation |
@RolesReferenced | |
@RunAs |
Le motif de conception injection de dépendance permet à une entité extérieure à un objet de lui fournir toutes les références sur les objets dont il dépend.
Avec Java EE 5, l'injection de dépendance peut être mise en oeuvre sur plusieurs types de ressources utilisés par un composant :
Trois annotations permettent de mettre en oeuvre l'injection de dépendance :
Ces annotations peuvent être utilisées dans tout objet dont le cycle de vie est géré par un conteneur du serveur d'applications (EJB, service web, servlet, bean entité, ...).
L'injection de dépendance peut donc être mise en oeuvre dans les trois conteneurs de la plate-forme : EJB, web et client.
Ceci permet d'éviter l'utilisation directe de l'API JNDI pour obtenir une instance de la ressource stockée dans l'annuaire.
La nouvelle API Java Persistence API, développée sous la JSR 220, est ajoutée à la version 5.0 de la plate-forme Java EE. Cette API peut être utilisée dans les EJB mais aussi dans toutes les autres applications même celles utilisant Java SE. Son utilisation n'est ainsi pas réservée qu'à des développements avec la plate-forme Java EE.
Cette API propose les fonctionnalités suivantes :
Les entités sont de simples POJO enrichis d'annotations dédiées. Ces annotations permettent de préciser comment est réalisé le mapping entre une ou plusieurs tables d'une base de données et l'entité.
Exemple : |
package fr.jmdoudoux.dej.jpa;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Personne implements Serializable {
@Id
@GeneratedValue
private int id;
private String prenom;
private String nom;
private static final long serialVersionUID = 1L;
public Personne() {
super();
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public String getPrenom() {
return this.prenom;
}
public void setPrenom(String prenom) {
this.prenom = prenom;
}
public String getNom() {
return this.nom;
}
public void setNom(String nom) {
this.nom = nom;
}
} |
JPA propose une API pour manipuler ces entités notamment en utilisant un objet de type EntityManager.
Exemple : rechercher et supprimer une occurrence |
private EntityManager em;
...
Personne personne = em.find(Personne.class, 4);
if (personne == null) {
System.out.println("Personne non trouvée");
} else {
em.remove(personne);
} |
La mise en oeuvre de JPA est détaillée dans le chapitre «JPA (Java Persistence API)»
La simplification de JAVA EE 5 concerne aussi les services web : les services web sont plus simples à développer et le nombre de standards supportés a augmenté. Cette simplification est largement assurée par l'utilisation des annotations et de comportements par défaut.
Exemple : |
package fr.jmdoudoux.dej.jaxws;
import javax.jws.WebService;
@WebService
public class MonService {
public String saluer(String param) {
return "Bonjour " + param;
}
} |
Avec Java EE 5, l'utilisation d'annotations a grandement simplifié le développement de services web.
Java EE 5 propose aussi plusieurs API concernant les services web : Java API for XML-Based Web Services (JAX-WS) 2.0 (JSR 224), Java Architecture for XML Binding (JAXB) 2.0 (JSR 222) et Web Services Metadata for the Java Platform (JSR 181).
JAX-WS 2.0 est la nouvelle API pour le développement de services web. Elle succède à JAX-RPC 1.1. Cette nouvelle version propose :
La définition d'un service web consiste à utiliser l'annotation @WebService sur une classe.
Par défaut, toutes les méthodes publiques sont exposées en tant qu'opérations du service web. L'utilisation des annotations permet de ne pas avoir à définir de fichier de déploiement.
Pour modifier le mapping par défaut, certaines annotations peuvent être utilisées.
Exemple : |
package fr.jmdoudoux.dej.jaxws;
import javax.jws.WebService;
import javax.jws.WebMethod;
@WebService(name="MonServiceWS")
public class MonService {
@WebMethod(operationName="direBonjour")
public String saluer(String param) {
return "Bonjour " + param;
}
} |
Par défaut, le WSDL d'un service web sera généré dynamiquement par le conteneur selon les spécifications de JAX-WS 2.
JAX-WS 2.0 propose aussi une API pour permettre l'appel de services web par un client de façon asynchrone. Cet appel asynchrone peut être utilisé avec n'importe quel service web : l'invocation de services web de façon asynchrone n'implique aucun traitement particulier côté serveur. C'est simplement l'invocation côté client qui est différente.
Le framework Java Server Faces version 1.2 est inclus dans la plate-forme Java EE 5.
La bibliothèque JavaServer Pages Standard Tag Library (JSTL) est incluse dans la plate-forme Java EE 5. JSTL propose un langage d'expression pour faciliter la manipulation d'entités et un ensemble de tags personnalisés.
Les incompatibilités entre les langages d'expressions de la JSTL et des JSF ont été corrigées, ce qui leur permet d'être utilisés simultanément grâce à UEL (Unified EL).
La version 2.0 de JAXB offre un support complet des schémas XML.
L'API Streaming API for XML (StAX) défini une méthode pour parser un document XML à partir d'événements. Son mode de fonctionnement est différent de SAX : avec SAX le développeur écrit du code pour répondre à des événements émis par le parser, avec StAX c'est le programme qui pilote le parser.
Remarque : ces deux API ont été ajoutées à la version 6 de Java SE.
Téléchargez le fichier java_ee_sdk-5-windows.exe sur le site de Sun et exécutez le.
Les fichiers d'installation sont extraits puis le programme d'installation est lancé pour guider l'utilisateur avec un assistant :
Cliquez sur le bouton «OK» puis sur le bouton « Finish »
Ouvrez un navigateur sur l'url http://localhost:8082
La version 6 de la plate-forme Java EE est diffusée depuis décembre 2009. Elle s'appuie sur la plate-forme Java SE 6 dont elle utilise de nombreuses API (JDBC, JNDI, JAXB, JAXP, RMI, JMX, ...).
Cette nouvelle version de la plate-forme a plusieurs caractéristiques :
L'implémentation de référence est le projet open source GlassFish version 3.
C'est la version de la plate-forme avec le plus grand nombre de spécifications. Elle contient 28 spécifications :
Technologies |
JSR |
Java Platform, Enterprise Edition 6 (Java EE 6) (avec Managed Beans 1.0) |
|
Technologies relatives aux services web |
|
Java API for RESTful Web Services (JAX-RS) 1.1 |
|
Implementing Enterprise Web Services 1.3 |
|
Java API for XML-Based Web Services (JAX-WS) 2.2 |
|
Java Architecture for XML Binding (JAXB) 2.2 |
|
Web Services Metadata for the Java Platform |
|
Java API for XML-Based RPC (JAX-RPC) 1.1 |
|
Java APIs for XML Messaging 1.3 |
|
Java API for XML Registries (JAXR) 1.0 |
|
Technologies relatives aux développements web |
|
Java Servlet 3.0 |
|
JavaServer Faces 2.0 |
|
JavaServer Pages 2.2/Expression Language 2.2 |
|
Standard Tag Library for JavaServer Pages (JSTL) 1.2 |
|
Debugging Support for Other Languages 1.0 |
|
Technologies relatives aux développements d'applications |
|
Contexts and Dependency Injection for Java (Web Beans 1.0) |
|
Dependency Injection for Java 1.0 |
|
Bean Validation 1.0 |
|
EnterpriseJava Beans 3.1 (avec Interceptors 1.1) |
|
Java EE Connector Architecture 1.6 |
|
Java Persistence 2.0 |
|
Common Annotations for the Java Platform 1.1 |
|
Java Message Service API 1.1 |
|
Java Transaction API (JTA) 1.1 |
|
JavaMail 1.4 |
|
Gestion et sécurité |
|
Java Authentication Service Provider Interface for Containers |
|
Java Authorization Contract for Containers 1.3 |
|
Java EE Application Deployment 1.2 |
|
J2EE Management 1.1 |
Une critique récurrente de la plate-forme Java EE est qu'elle est très riche et donc complexe. La plupart des applications de petite taille ou de taille moyenne n'ont pas besoin de toutes les technologies proposées par la plate-forme.
Cette richesse est aussi liée au fait que certaines technologies sont obsolètes car remplacées par une nouvelle technologie : ces anciennes versions sont cependant conservées pour des raisons de compatibilité.
Java EE 6 définit la notion de profile qui est un sous-ensemble et/ou un sur-ensemble de Java EE 6 pour des besoins particuliers.
Les profiles sont conçus pour proposer une solution technique particulière pour des besoins spécifiques. Cela permet à un fournisseur de n'avoir à proposer que le support des technologies incluses dans le profile plutôt que d'avoir à implémenter toutes celles de la plate-forme Java EE.
Java EE 6 définit un premier profile : le web profile qui se concentre sur le développement d'applications de type web. Il doit pouvoir être exécuté dans un simple conteneur web car le packaging se fait dans une archive de type war.
Le web profile est composé de plusieurs spécifications pour définir un sous-ensemble de Java EE :
Servlet 3.0 |
JSP 2.2 |
EL 1.2 |
JSTL 1.2 |
JSF 2.0 |
EJB Lite 3.1 |
JTA 1.1 |
JPA 2.0 |
Bean Validation 1.0 |
DI 1.0 |
CDI 1.0 |
Interceptors 1.1 |
D'autres profiles devraient être définis ultérieurement de façon indépendante des évolutions de la plate-forme Java EE.
Un fournisseur n'a plus l'obligation de fournir une implémentation complète de la spécification Java EE mais peut simplement fournir une implémentation d'un profile. Bien sûr dans ce cas, les fonctionnalités utilisables sont uniquement définies dans ce profile.
La notion de profile a fait l'objet de nombreux débats au sein des membres de la JSR notamment sur sa définition, la compatibilité et sur la confusion et les interrogations qu'elle peut susciter chez les développeurs.
La plate-forme Java EE est devenue au fil des versions imposante en terme de nombre de spécifications, de fonctionnalités et d'API. Aucunes des précédentes versions n'a supprimé de fonctionnalités même si certaines sont obsolètes car remplacées, rarement adoptées ou utilisées. Cela pose plusieurs problèmes :
Certaines de ces fonctionnalités sont de plus obsolètes car remplacées par une plus récente ou ne sont que peu ou pas utilisées.
Java EE 6 entame donc une cure d'amaigrissement de la plate-forme en définissant un ensemble d'API déclarées comme pruned.
Les fonctionnalités déclarées pruned dans Java EE 6 sont :
Elles doivent toujours être disponibles dans une implémentation de Java EE 6 mais elles seront certainement amenées à disparaître dans la prochaine version de la plate-forme Java EE et leur support ne sera plus obligatoire dans les implémentations des serveurs d'applications. Le concept de pruned est plus fort que le concept de deprecated de la plate-forme Java SE.
Il est donc raisonnable de ne plus utiliser ces fonctionnalités dans de nouveaux développements et de migrer progressivement les applications existantes qui les utilisent.
Le but est de simplifier le développement des prochaines versions de conteneurs des serveurs d'applications qui n'auront plus l'obligation de fournir une implémentation des fonctionnalités déclarées pruned.
Plusieurs spécifications existantes dans la version 5 de Java EE 5 ont été mises à jour dans la plate-forme Java EE 6.
Cette nouvelle version de l'API servlet a pour but de simplifier son utilisation. Comme pour la plupart des API de Java EE, cette simplification repose en grande partie sur l'utilisation d'annotations telles que @WebServlet, @ServletFilter, @WebServletContextListener, @InitParam, @WebFilter, ... pour déclarer des entités ce qui permet de rendre le descripteur de déploiement web.xml plus léger voire optionnel.
Bien qu'une servlet puisse être annotée avec @WebServlet, elle doit toujours hériter de la classe HttpServlet notamment pour permettre d'identifier de façon unique les méthodes à invoquer selon le type de requête http à traiter.
Même si la plupart des développements n'utilise plus directement cette API au profit de frameworks, les développeurs de ces derniers vont pouvoir utiliser les nouvelles fonctionnalités de la spécification.
Le fichier web.xml est rendu modulaire et peut être rédigé sous la forme de fragments qui seront agrégés et fusionnés par le conteneur au moment du déploiement.
Un fragment est une portion du descripteur de déploiement dont le tag racine est <web-fragment> qui peut contenir la définition de tout ou partie des entités configurables dans le descripteur de déploiement.
Ceci pourra ainsi permettre d'éviter d'avoir à déclarer des servlets ou des filtres d'un framework utilisés dans une webapp. Le framework pourra simplement définir le fragment pour que ces déclarations soient prises en compte par le conteneur.
Le conteneur recherche des fragments du fichier web.xml dans le classpath de la webapp (WEB-INF/classes et dans les fichiers jar du répertoire WEB-INF/lib) pour les agréger et composer le fichier web.xml.
Servlet 3.0 propose un support des invocations asynchrones en utilisant l'attribut asyncSupported=True de l'annotation @WebServlet. Une api dédiée est proposée pour gérer l'état d'une requête.
L'interface ServletContext propose des méthodes pour permettre d'enregistrer dynamiquement des servlets, des filtres et des listeners.
L'implémentation de référence est GlassFish v3.
Cette nouvelle version de JSF a pour but de simplifier son utilisation. Comme pour la plupart des API de Java EE, cette simplification repose en grande partie sur l'utilisation d'annotations telles que @ManagedBean, @ManagedProperty, @ApplicationScoped, @SessionScoped, @FacesValidator, @FacesConverter ... qui permettent de rendre le fichier faces-config.xml beaucoup plus petit.
JSF 2.0 utilise le projet open source Facelets comme technologie pour la partie vue : l'organisation du contenu des pages et des composants est facilitée grâce à l'utilisation de Facelets. Le développement de composants a été grandement simplifié grâce à Facelets en utilisant la notion de composition qui met en oeuvre XHTML et un tag JSF.
JSF propose en standard un support de fonctionnalités mettant en oeuvre Ajax sur des fonctions JavaScript standardisées contenues dans le fichier jsf.js que chaque implémentation doit fournir. Le cycle de vie de traitement d'une requête JSF a dû être adapté pour les traitements Ajax en incorporant la notion de page partielle (partial page).
L'implémentation de référence est Mojorra.
La version 3.1 des EJB poursuit l'effort de simplification de la version 3.0 tout en apportant de nouvelles fonctionnalités et un enrichissement des fonctionnalités existantes :
L'implémentation de référence est GlassFish v3.
Le chapitre «Les EJB 3.1» contient une description détaillée de cette API.
JPA 2.0 a fait l'objet d'une spécification dédiée.
Les possibilités de mapping sont enrichies avec
La version 2.0 de JPA propose de nouvelles fonctionnalités manquantes dans la version précédente :
L'implémentation de référence est EclipseLink.
Cette API permet la mise en oeuvre de services web de type Soap. La version 2.2 est incluse dans Java EE 6.
L'implémentation de référence est Metro.
Ils peuvent être utilisés sur les EJB et les Managed Beans.
De nouvelles API ont été ajoutées à la version 6 de la plate-forme Java EE.
L'API JAX-RS permet de mettre en oeuvre des services web de type RestFul.
L'inclusion de JAX-RS 1.1 dans la plate-forme Java EE suit la tendance à l'adoption grandissante des services web de type REST.
JAX-RS utilise des annotations sur des POJO pour masquer la complexité de traitement des requêtes et de génération des réponses ce qui permet de simplifier leurs mises en oeuvre.
Plusieurs annotations sont définies :
Cette API repose sur l'utilisation de ces annotations sur un POJO.
La version utilisée dans Java EE 6 est la 1.1.
Exemple : |
@Path("/helloworld")
public class HelloWorldRS {
@GET
@Produces("text/plain")
public String saluer() {
return "Hello World";
}
}
|
Cette version permet une utilisation de l'API avec les EJB.
L'implémentation de référence est Jersey.
Le but de cette spécification est de faciliter les interactions entre la couche de présentation, la couche métier et la couche de persistance notamment à l'aide de beans qui pourront être utilisés par plusieurs couches.
Cette spécification a été influencée par plusieurs projets open source notamment JBoss Seam, Google Guice et Spring.
CDI a pour objectif de fournir une glue entre les couches mettant en oeuvre JSF, EJB et JPA. Elle permet notamment d'enregistrer et de gérer des EJB, des entités JPA et des ManagedBeans sous la forme de composants qui seront injectables et utilisables grâce à EL (Expression Language).
CDI peut remplacer les backing beans de JSF.
La gestion du cycle de vie des composants par CDI se fait par rapport à un contexte (requête, session et application mais aussi deux nouveaux contextes nommés dependent et conversation).
L'implémentation de référence est JBoss Seams.
Le but de cette JSR est de proposer la standardisation d'un ensemble d'annotations utilisables avec n'importe quel moteur d'injection : le but n'est pas de spécifier un tel moteur.
Elle définit plusieurs annotations :
Google Guice et Spring 3.0 implémentent cette spécification.
Cette API standardise la validation de données.
Les contraintes sont définies dans les beans avec des annotations (@NotNull, @Size, @Past, ...)
Bean Validation propose une API pour valider des données, définir ses propres contraintes et rechercher des contraintes.
Cette API est utilisée notamment par JSF 2.0 et JPA 2.0
L'implémentation de référence est Hibernate Validator 4.0.
Le chapitre «La validation des données» contient une description détaillée de cette API.
C'est un modèle de composants légers : ce sont des POJO gérés par le conteneur.
Les managed beans supportent plusieurs services :
Un managed bean est un POJO annoté avec l'annotation @javax.annotation.ManagedBean. Cette annotation est issue de la JSR 250 (Commons annotations).
Les spécifications de Java EE 7 sont définies dans la JSR 342. Cette spécification ne définit pas directement d'API mais elle liste celles qui sont incluses dans la plate-forme et comment celles-ci interagissent entre-elles. Elle définit aussi des éléments précis de la plate-forme comme les transactions, la sécurité, l'assemblage, le déploiement, ...
Java EE 7 a plusieurs objectifs :
Les spécifications de Java EE 7 furent officiellement diffusées en juin 2013. Java EE 7 s'appuie sur Java SE 7. Cette spécification contient 14 nouvelles JSR et 9 versions de maintenance (Maintenance Release) de JSR.
Java EE 7 inclut plusieurs nouvelles API :
Java EE 7 inclut des API ayant une mise à jour majeure :
Java EE 7 inclut des API mises à jour :
Les JSR mises à jour (Maintenance Release) sont :
Initialement Java EE 7 devait intégrer la spécification Java Temporary Caching API 1.0 (JSR 107) et des fonctionnalités relatives au Cloud (par exemple State Management (JSR 350)) mais elles sont repoussées dans la prochaine version de Java EE.
Java EE 7 poursuit la simplification de l'utilisation de la plate-forme entamée depuis Java EE 5 notamment :
JAX-RS 2.0 est ajoutée dans le Web Profile.
L'implémentation de référence est la version 4.0 du serveur d'applications Glassfish.
La JSR 353 définit les spécifications d'une nouvelle API qui permet de produire et consommer des documents JSON. La version 1.0 ne propose rien concernant le binding entre un document et des objets Java.
Elle propose deux API pour réaliser ces tâches :
Les principales interfaces de l'API Streaming, contenues dans le package javax.json.stream sont :
Les principales interfaces de l'API Model, contenues dans le package javax.json sont :
Pour permettre une utilisation de différentes implémentations, l'API propose des fabriques.
L'utilisation de cette API est détaillée dans le chapitre «JSON-P».
WebSocket est un protocole de communication bi-directionnel en mode full duplex
Les WebSockets sont standardisés par l'IETF sous la RFC 6455
Les WebSockets font parties des spécifications HTML 5 : l'API Javascript définie par le W3C est à l'état Candidat Recommendation
La JSR 356 définit les spécifications de l'API « Java API for WebSocket 1.0 » qui propose une utilisation côté client et serveur.
Elle propose deux modèles de développement :
L'API WebSocket 1.0 définit plusieurs annotations
Annotation |
S'applique sur |
Rôle |
@ServerEndPoint |
Classe |
Déclarer la classe comme étant un endpoint client de la websocket |
@OnOpen |
Méthode |
Intercepter l'ouverture de la websocket |
@OnMessage |
Méthode |
Intercepter un message de la websocket |
@PathParam |
Paramètre d'une méthode |
Définir un paramètre dont la valeur sera extraite de l'URI |
@OnError |
Méthode |
Intercepter les erreurs durant les échanges |
@OnClose |
Méthode |
Intercepter la fermeture du websocket |
@ClientEndPoint |
Classe |
Déclarer la classe comme étant un client du websocket |
Elle consiste essentiellement à réagir à certains événements liés au cycle de vie d'une WebSocket.
La mise en oeuvre repose sur plusieurs concepts :
L'utilisation de cette API est détaillée dans le chapitre «L'API Websocket».
La JSR 352 propose une standardisation d'une API pour le développement de traitements de type batch. Aussi appelé traitements par lots, ce type d'applications existe depuis toujours dans l'informatique : elle permet de traiter grâce à différentes étapes de grandes quantités de données avec des algorithmes plus ou moins complexes sans interaction si tout se passe bien.
Les traitements batch ou traitements par lot (batch processing) sont des traitements automatisés sur un ensemble de données. Généralement ces traitements effectuent des opérations complexes ou lourdes sur un volume conséquent de données : leurs temps d'exécution est généralement long, ce qui les empêchent d'être exécutés en temps réels.
Les traitements métier d'un batch sont généralement composés d'une ou plusieurs étapes.
La spécification ne précise rien concernant la planification de l'exécution des batches car différentes solutions existent déjà notamment les EJB Timer dans la plate-forme Java EE.
La JSR 352 est une spécification qui définit un modèle de programmation pour des traitements batch.
Ce modèle repose sur plusieurs concepts :
Lors de l'exécution d'un batch, plusieurs concepts sont utilisés :
Les classes et interfaces de l'API Batch processing sont contenues dans le package javax.batch.
Un job est un traitement qui peut être composé d'une ou plusieurs étapes (Step).
Un Step peut être de deux types :
Un step de type chunked met en oeuvre le modèle de conception lecture/traitement/écriture (read/process/write) d'un élément. Pour cela, trois types de classes sont définies : ItemReader, ItemProcessor et ItemWriter. Chaque élément est lu et traité.
Exemple : |
package fr.jmdoudoux.dej.javaee7.batch;
import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
import javax.batch.api.chunk.AbstractItemReader;
import javax.ejb.EJB;
import javax.inject.Named;
@Named("MonItemReader")
public class MonItemReader extends AbstractItemReader
{
@EJB
private ElementBean elementBean;
Iterator<Element> elementsIterator;
@Override
public void open(Serializable e) throws Exception {
List<Element> elements = elementBean.getElements();
elementsIterator = elements.iterator();
}
@Override
public Object readItem() throws Exception {
return elementsIterator.hasNext() ? elementsIterator.next() : null;
}
} |
Exemple : |
package fr.jmdoudoux.dej.javaee7.batch;
import javax.batch.api.chunk.ItemProcessor;
import javax.inject.Named;
@Named("MonItemProcessor")
public class MonItemProcessor implements ItemProcessor {
@Override
public Object processItem(Object obj) throws Exception {
Element element = (Element) obj;
int valeur = element.getValeur();
element.setValeur(valeur + 10);
return element;
}
} |
L'écriture des éléments se fait par paquets : la gestion des checkpoints dans les transactions est configurable dans ce modèle ce qui permet d'avoir des commit à intervalles réguliers.
Un step de type Bachlet ne repose sur aucun modèle prédéfini : les traitements sont invoqués une seule fois dans leur intégralité et se terminent.
Le contrôle des Jobs se fait grâce au JSL (Job Specification Language). Le JSL est un document XML qui permet de décrire les fonctionnalités d'un Job.
Exemple : |
<?xml version="1.0" encoding="UTF-8"?>
<job id="monJob" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
version="1.0">
<step id="traitement">
<chunk item-count="1">
<reader ref="MonItemReader"></reader>
<processor ref="MonItemProcessor"></processor>
<writer ref="MonItemWriter"></writer>
</chunk>
</step>
</job> |
L'API propose un support de fonctionnalités avancées notamment :
Il ne faut pas utiliser l'API Concurrency de Java SE dans une application Java EE. Le but de la spécification Concurrency Utilities définit par la JSR 236 est de permettre la mise en oeuvre des traitements concurrents dans un conteneur Java EE. Elle enrichit la JSR 166.
Les spécifications de cette API ont plusieurs objectifs :
Les classes et interfaces de cette spécifications sont dans le package javax.enterprise.concurrent.
Chaque serveur d'applications Java EE propose une implémentation de l'interface ManagedExecutorService qui hérite de l'interface java.util.concurrent.ExecutorService. Pour obtenir une instance, il faut soit se la faire injecter sous la forme d'une ressource soit l'obtenir grâce à un lookup JNDI (dans ce dernier cas, il est nécessaire de déclarer la ressource dans un descripteur de déploiement).
Exemple ( code Java 7 ) : |
@Resource(name="concurrent/monExecutor")
ManagedExecutorService managedExecutor; |
Exemple dans le description de déploiement web.xml d'une webapp
Exemple : |
<resource-env-ref>
<resource-env-ref-name>concurrent/monExecutor</resource-env-ref-name>
<resource-env-ref-type>javax.enterprise.concurrent.ManagedExecutorService
</resource-env-ref-type>
</resource-env-ref> |
Il est possible de définir plusieurs ManagedExecutorService avec différentes configurations dans le serveur d'applications, chacun ayant un nom permettant de les identifier, en les associant au sous contexte JNDI java:comp/env/concurrent.
Les traitements qui seront exécutés par le ManagedExecutorService doivent être encapsulés dans une classe qui doit implémenter l'interface java.lang.Runnable ou java.util.concurrent.Callable
Exemple ( code Java 7 ) : |
public class MaTache implements Runnable {
public void run() {
// Traitements a effectuer
}
} |
Le plus simple pour demander l'exécution d'une tâche est de passer son instance en paramètre de la méthode submit(). Elle renvoie une instance de type java.util.concurrent.Future qui permet de gérer et de déterminer le résultat de manière asynchrone.
La méthode invokeAll() permet de demander l'exécution de plusieurs tâches passées en paramètres sous la forme d'une collection de type List<Callable<T>>.
Exemple ( code Java 7 ) : |
package fr.jmdoudoux.dej.concurrency;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import javax.enterprise.concurrent.ManagedExecutorService;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(name = "MaServlet", urlPatterns = {"/MaServlet"})
public class MaServlet extends HttpServlet {
@Resource(name = "concurrent/monExecutor")
ManagedExecutorService mes;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
try (PrintWriter out = response.getWriter()) {
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<title>Test JSR 236</title>");
out.println("</head>");
out.println("<body>");
out.println("<p>Tache lancée à " + new Date() + "</p>");
MaTache maTache = new MaTache();
Future maTacheFuture = mes.submit(maTache);
while (!(maTacheFuture.isDone() || maTacheFuture.isCancelled())) {
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
}
}
out.println("<p>Tache terminée à " + new Date() + "</p>");
out.println("<p>Taches lancées à " + new Date() + "</p>");
ArrayList<Callable<Date>> taches = new ArrayList<>();
taches.add(new MaSecondeTache(2000));
taches.add(new MaSecondeTache(5000));
List<Future<Date>> res = null;
try {
res = mes.invokeAll(taches);
out.println("<p>Tache 1 terminée à " + res.get(0).get() + "</p>");
out.println("<p>Tache 2 terminée à " + res.get(1).get() + "</p>");
} catch (InterruptedException | ExecutionException ex) {
Logger.getLogger(MaServlet.class.getName()).log(Level.SEVERE, null, ex);
}
out.println("</body>");
out.println("</html>");
}
}
} |
Chaque implémentation du serveur d'applications Java EE propose ses propres possibilités de configuration et les fonctionnalités qui leur sont associées.
L'interface javax.enterprise.concurrent.ManagedScheduledExecutorService hérite des interfaces javax.enterprise.concurrent.ManagedExecutorService et java.util.concurrent.ScheduledExecutorService pour permettre de décaler l'exécution de tâches ou permettre leur exécution de manière répétitive selon un certain délai.
Pour soumettre l'exécution d'une tâche, il est possible d'utiliser une des méthodes submit(), invokeXXX() ou scheduleXXX(). Deux surcharges de la méthode schedule() attendent en paramètres un objet de type javax.enterprise.concurrent.Trigger qui permet de définir les conditions de déclenchement de l'exécution.
Exemple ( code Java 7 ) : |
@Resource(name="concurrent/monScheduledExecutor")
ManagedScheduledExecutorService executor;
// ...
Future future = executor.schedule(new MaTache(), 5, TimeUnit.SECONDS); |
Une classe qui implémente une tâche peut optionnellement implémenter l'interface ManagedTask pour permettre de fournir des informations d'exécution et enregistrer un ManagedTaskListener qui recevra et traitera des événements sur le cycle de vie de la tâche.
L'interface ManagedThreadFactory qui hérite de l'interface java.util.concurrent.ThreadFactory définit les fonctionnalités d'une fabrique de threads gérés par le conteneur. Les threads obtenus en invoquant la méthode newThread() doivent implémenter l'interface ManageableThread.
Une instance de type ManagedThreadFactory doit être définie dans le contexte JNDI et une référence vers cette instance doit être déclarée dans le descripteur de déploiement pour permettre un lookup JNDI.
Exemple : |
<resource-env-ref>
<resource-env-ref-name>concurrent/maThreadFactory</resource-env-ref-name>
<resource-env-ref-type>javax.enterprise.concurrent.ManagedThreadFactory
</resource-env-ref-type>
</resource-env-ref> |
Il est aussi possible de demander l'injection de l'instance et de l'utiliser dans le code.
Exemple ( code Java 7 ) : |
@Resource(name = "concurrent/maThreadFactory")
ManagedThreadFactory threadFactory;
// ...
MaTache maTache = new MaTache();
Thread thread = threadFactory.newThread(maTache); |
La précédente version, la 1.1, a été publiée en 2003. Pourtant cette API est largement utilisée.
Les spécifications de la version 2.0 de JMS sont dans la JSR 343.
La version 2.0 de l'API JMS a pour but de simplifier l'utilisation de l'API en réduisant la quantité de code nécessaire à sa mise en oeuvre.
La version 2.0 de JMS définit une nouvelle API et simplifie l'API existante notamment :
Le but de ces évolutions est de maintenir la compatibilité ascendante tout en simplifiant le code à écrire pour utiliser JMS.
L'utilisation de l'API JMS 1.1, pour par exemple envoyer un message, présente plusieurs inconvénients :
Exemple ( code Java 7 ) : |
@Resource(lookup = "java:global/jms/mqConnectionFactory")
ConnectionFactory connectionFactory;
@Resource(lookup = "java:global/jms/maQueue")
Queue maQueue;
public void sendMessage(String contenu) {
try {
Connection connection = connectionFactory.createConnection();
try {
Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
MessageProducer messageProducer = session.createProducer(maQueue);
TextMessage textMessage = session.createTextMessage(contenu);
messageProducer.send(textMessage);
} finally {
connection.close();
}
} catch (JMSException ex) {
// traitement de l'exception
}
} |
Pour conserver la compatibilité, les modifications dans l'API existante ont été limitées.
En plus des méthodes existantes qui sont conservées, la classe javax.jms.Connection possède de nouvelles méthodes :
Les principaux objet de JMS (Connection, Session, MessageProducer, MessageConsumer, QueueBrowser) implémentent AutoCloseable pour permettre leur utilisation avec l'instruction try with ressources.
Exemple ( code Java 7 ) : |
@Resource(lookup = "jms/mqConnectionFactory")
ConnectionFactory cf;
@Resource(lookup="jms/maQueue")
Destination dest;
public void sendMessage (String contenu) throws JMSException {
try ( Connection conn = connectionFactory.createConnection();
Session session = conn.createSession();
MessageProducer producer = session.createProducer(dest);){
Message mess = sess.createTextMessage(payload);
producer.send(mess);
} catch(JMSException e){
// traitement de l'exception
}
} |
Pour faciliter l'utilisation de JMS, la version 2.0 introduit de nouveaux concepts dans une API simplifiée.
Envoi d'un message avec l'API simplifiée de JMS 2.0
Exemple ( code Java 7 ) : |
@Resource(lookup = "jms/mqConnectionFactory")
ConnectionFactory connectionFactory;
@Resource(lookup = "jms/maQueue")
Queue maQueue;
public void sendMessage (String contenu) {
try (JMSContext context = connectionFactory.createContext();){
context.createProducer().send(maQueue, contenu);
} catch (JMSRuntimeException ex) {
// traitement de l'exception
}
} |
L'interface JMSContext définit les fonctionnalités d'objets qui encapsulent une connexion et une session et ainsi facilite la création d'objets de l'API JMS.
Pour obtenir une instance, il suffit d'invoquer la méthode createContext() de la classe ConnectionFactory ou de demander au conteneur d'en injecter une instance.
L'interface JMSProducer facilite la définition des propriétés et l'envoi de messages en utilisant un JMSContext. Pour en obtenir une instance, il faut invoquer la méthode createProducer().
Les méthodes de ces classes ne lèvent plus d'exceptions de type checked mais des exceptions de type unchecked.
Exemple ( code Java 7 ) : |
@Inject
JMSContext context;
@Resource(mappedName="maQueue")
Queue maQueue;
public void sendMessage(String contenu) {
context.createProducer().send(maQueue, contenu);
} |
La JSR 349 spécifie la version 1.1 de l'API BeanValidation qui propose notamment :
Exemple ( code Java 7 ) : |
public void MaMethode(@NotNull String contenu) {
context.createProducer().send(maQueue, contenu);
}
@Future
public Date determinerProchaineEcheance() {
// ...
} |
La JSR 339 définit les spécifications de la version 2.0 de l'API JAX-RS.
La version 2.0 propose notamment :
La JSR 340 définit les spécifications de la version 3.1 de l'API Servlets.
Cette version apporte plusieurs améliorations à l'API :
La prise en charge de l'option upgrade du protocole HTTP se fait grâce à la méthode upgrade() de la classe HttpServletRequest qui attend en paramètre le type d'une classe implémentant l'interface HttpUpgradeHandler.
L'interface HttpUpgradeHandler définit deux méthodes :
Méthode |
Rôle |
void destroy() |
Méthode invoquée lorsque la connexion est fermée |
void init(WebConnection wc) |
Méthode invoquée lors la connexion est prête à utiliser le nouveau protocole |
La version 2.1 de JPA, spécifiée dans la JSR 338, ajoute quelques fonctionnalités manquantes dans les versions précédentes, notamment :
La JSR 907 définit les spécifications de la version 1.2 de JTA.
Cette version propose le support de la déclaration de transactions en dehors des EJB grâce à l'utilisation des intercepteurs de CDI.
Cette déclaration se fait en utilisant une nouvelle annotation : javax.transaction.Transactional.
Exemple ( code Java 7 ) : |
public class MaClasse {
// ...
@Transactional
public void maMethode() {
// ...
}
// ...
} |
Elle peut avoir en attribut une énumération de type TxType qui par défaut vaut TxType.REQUIRED.
L'énumération TxType définit plusieurs valeurs : REQUIRED, REQUIRED_NEW, MANDATORY, SUPPORTS, NOT_SUPPORTED, NEVER
Les spécifications de Java EE 8 sont définies dans la JSR 366. Cette spécification ne définit pas directement d'API mais elle liste celles qui sont incluses dans la plate-forme et comment celles-ci interagissent entre-elles. Elle définit aussi des éléments précis de la plate-forme comme les transactions, la sécurité, l'assemblage, le déploiement, ...
Les spécifications de Java EE 8 furent officiellement diffusées en août 2017. Java EE 8 s'appuie sur Java SE 8. Cette spécification contient 2 nouvelles API, 8 mises à jour majeures et des versions de maintenance (Maintenance Release) de JSR.
La version 8 est une version qui propose :
Java EE 8 inclut deux nouvelles API :
Java EE 8 inclut des API ayant une mise à jour majeure :
Java EE 8 inclut des API mises à jour :
L'implémentation de référence est la version 5.0 du serveur d'applications open source Glassfish.
|