Java EE 7, plus qu’un nouveau numéro de version ?

Java EE 7, c’est parti !

La semaine dernière Oracle a annoncé la sortie de Java EE 7, en nous promettant (je cite) “le support de HTML5, plus de productivité pour les développeurs et la réponse aux besoins les plus exigeants des entreprises”.

Qu’en est-il vraiment ?

Etat des lieux de Java EE

Si Java est aujourd’hui le principal language utilisé en entreprise, Java EE n’a pas eu le même succès, la plupart des gens n’en utilisant qu’un sous-ensemble (JSP, Servlet, JPA, etc.) et non pas l’ensemble des APIs (EJBs, JMS…).

Les premières versions de la plateforme, mal conçues, ont été rapidement concurrencées par des frameworks tels que Spring : au bout de quelques années de concurrence, J2EE est devenu Java EE et a repris les principes majeurs de Spring tels que l’injection de dépendance par annotation ou les intercepteurs (encore qu’on pourrait argumenter que les intercepteurs Java EE sont nettement moins puissants que l’AOP fourni par Spring).

Cependant, entre-temps, notre monde a bougé : la productivité ou la satisfaction des développeurs n’est plus simplement limité à avoir un framework d’injection de dépendance ! Nous voulons pouvoir développer des applications REST, HTML5, dans le cloud, avec la stack ayant le plus de buzzwords possibles. Et j’oubliais la mobilité et le Big Data, sur des architectures distribuées 🙂

Que ce soit sur Google Trends (tendances des recherches Google) ou Indeed (tendances des offres d’emploi aux US), on retrouve les mêmes courbes :

On voit bien ici que l’intérêt des développeurs pour Java EE n’a pas décollé, par rapport à des frameworks concurrents (node.js) ou des technologies NoSQL/Big Data.

C’est donc sur ces thèmes que Java EE doit se battre, en particulier contre Spring ou Node.js, qui sont des stacks ayant pris depuis longtemps le chemin des applications HTML5, REST, NoSQL, mobiles, dans le cloud, etc. Et c’est ce que nous allons donc étudier tout au long de cet article.

Le support de HTML5, 1ère partie : les Websockets

Le support de HTML5 m’a personnellement plutôt fait sourire : quel rapport entre Java EE et le HTML5 ? Pour Oracle, dans sa “press release”, cela signifie supporter les Websockets !

Quiconque ayant déjà fait des Websockets se méfie en voyant ce type d’annonce :

  • Utiliser des Websockets est une problématique bien plus compliquée que d’avoir simplement une implémentation sur son serveur d’application. Il est clair que la solution proposée par Java EE va poser des problèmes de portabilité et de gestion des erreurs (que faites-vous si un serveur proxy ou un navigateur client ne supporte pas Websocket ?).
  • Les Websockets changent radicalement la manière dont on conçoit une application, car l’idée est de pouvoir faire du “push” depuis le serveur, ce qui est très différent d’une architecture classique où l’on répond à des requêtes envoyées par un client HTTP. La seule solution en Java EE consiste à utiliser JMS 2.0 pour faire ces envois (mécanisme détaillé dans ce blog), ce que je trouve plutôt lourd. Sortir un serveur JMS pour faire des Websockets, c’est quand même bien compliqué !

Pour utiliser Atmosphere depuis pas mal de temps, un excellent framework qui résout tous ces problèmes de manière performante et élégante, je vois mal quiconque utiliser Java EE 7 directement.

La press release d’Oracle met donc en avant une avancée technique nécessaire et intéressante, mais dont l’implémentation reste simpliste.

Le support de HTML5, 2ème partie : JAX-RS 2 et JSON

Faire une application HTML5 avec un framework MVC JavaScript moderne, de type backbone.js ou angular.js, c’est surtout consommer des services REST, et s’échanger des données au format JSON.

La mise à jour de l’API JAX RS est donc particulièrement bienvenue, et permet :

  • D’avoir des intercepteurs sur ses services REST
  • De pouvoir avoir des services asynchrones
  • D’avoir une API cliente (il était en effet assez incroyable de constater qu’il y avait une API serveur mais pas d’API cliente !)

De même nous disposons maintenant d’une API JSON standardisée, avec JSON-P (plus de détails sur cet article). Une nouveauté intéressante est l’ajout d’une API fluente permettant de créer du JSON (personnellement je n’ai encore jamais eu ce besoin, mais cela peut toujours être utile).

Toutes ces fonctionnalités étant présentes dans les stacks concurrente (par exemple Spring MVC REST + Jackson 2), il s’agit donc là d’une mise à jour nécessaire.

Un regret cependant : cette stack ne propose pas de support pour réaliser des tests unitaires avec des mocks, comme nous en disposons dans Spring. C’est une fonctionnalité que j’apprécie particulièrement, par exemple dans Tatami (voici en exemple), et qui devrait bientôt faire l’objet d’un nouvel article sur ce blog.

Le support de HTML5, 3ème partie : JSF 2.2

De manière plus discrète, Java EE 7 amène également les “passthrough attributes” dans JSF 2.2, ce qui permet enfin d’utiliser HTML5 avec JSF 2.2.

Jusqu’à présent, on ne pouvait utiliser que les tags reconnus par sa librairie de composants : or, en HTML5, vous pouvez ajouter et définir vos propres attributs, que vous utilisez ensuite en JavaScript.

Les “passthrough attributes” sont en fait assez basiques : la librairie de composant va simplement rendre ces attributs côté client. Elle fait alors juste “passe plat” entre le code JSF et le HTML généré. Mais cela change tout, car nous pouvons maintenant avoir nos propres attributs côté client !

Pas de cloud dans Java EE 7

L’objectif de Java EE 7 était le cloud : comme présenté l’année dernière par Oracle (les slides sont encore ici), nous devions pouvoir développer “dans le cloud” avec Java EE 7, et plus précisément :

  • Avoir des APIs pour gérer le provisionning, l’élasticité, la qualité de service, etc.
  • Avoir des applications modulaires, avec Jigsaw
  • Avoir du “vrai” multi-tenancy sur les serveurs d’app
  • Enfin, JCache allait renaître de ses cendres et nous aurions une API de cache digne de ce nom

Au final, tout cela a été abandonné.

Pour avoir participé à la spécification JMS 2, je peux vous confirmer que cet abandon a été volontaire : aucun vendeur de serveur d’application ne souhaite voir ces fonctionnalités être intégrées dans Java EE. Cela fait plus de 10 ans que l’ajout de ces fonctionnalités “avancées” dans Java EE sont sabordées par une grande partie des acteurs du JCP, car ce sont grâce à elles que les entreprises clientes achètent des serveurs en “version entreprise” au lieu de se contenter d’un simple Tomcat.

C’est donc un grand gâchis, mais ce n’est que partie remise. Comme en son temps l’arrivée de Spring a fait bouger le JCP, l’arrivée du cloud va nécessairement faire bouger les lignes. A titre d’exemple, les ventes de serveurs d’Oracle (les anciens serveurs Sun, que Oracle a racheté) ont chuté de 27,2% ce trimestre ! Il est donc probable que le JCP, à nouveau, soit forcé de s’adapter.

Focus sur JMS 2

L’un des succès de Java EE 7 est l’arrivée de JMS 2. Plus de 10 ans après la norme précédente, et toujours sans support du clustering (cf. le point précédent), JMS 2 propose une API modernisée, qui vous permettra de vous passer de la fameuse JmsTemplate de Spring.

JMS 2, heureusement, garde quand même l’un des grands bénéfices de JMS 1, qui était de pouvoir être utilisé en dehors d’un serveur d’application : en effet, les vendeurs de serveurs d’applications voulaient lier JMS 2 à CDI, de manière à obliger les utilisateurs à avoir un serveur d’application pour envoyer un message. Au final, nous restons donc sur une API proche de l’originale, mais modernisée et simplifiée.

Cette nouvelle API a été très bien décrite dans ce blog, nous en retiendrons principalement :

  • La suppression de beaucoup de code inutile
  • La fin de l’API connection.createSession(true,Session.SESSION_TRANSACTED), dont les deux paramètres étaient une curiosité étonnante
  • L’ajout d’une API “fluente”, de type context.createProducer().setPriority(1).setProperty(“foo”, “bar”).send(demoQueue, textMessage);

La bonne surprise de Java EE 7 : l’intégration de Spring Batch

Lancé par IBM, l’intégration des batchs dans Java EE est enfin une réalité ! Dans la pratique, il s’agit d’une intégration du code Spring Batch dans Java EE :

  • L’API est la même
  • Les fichiers de configuration sont les mêmes
  • Même dans les slides d’Oracle, on retrouve des schémas copiés/collés du site de Spring Batch 🙂

D’autre part, SpringSource a fait le maximum pour que Spring Batch puisse être utilisé dans Java EE (avec CDI), mais sans que l’on soit obligé de dépendre de ses APIs.

Depuis le nombre d’années que l’on attendait une solution pour faire des batchs en Java EE, c’est donc une excellente nouvelle, d’autant plus que Spring Batch est une solution très largement reconnue.

Reste à voir quelles implémentations seront disponibles dans les différents serveurs d’applications :

  • Est-ce que les vendeurs de serveurs d’applications se contenteront tous de copier/coller le code de Spring Batch, ou certains feront-ils des implémentations spécifiques ?
  • Est-ce que nous aurons enfin des stratégies performantes de partitionning des batchs ? Les versions disponibles sur Spring Batch sont en effet en cours de développement depuis longtemps, sans grande avancée.

Cette nouvelle devrait également permettre de faire revivre Spring Batch, qui est un projet qui ne progressait plus beaucoup ces dernières années, en particulier depuis que Accenture en avait abandonné le co-développement avec SpringSource.

En conclusion

Cette montée de version de Java EE, tant attendue, n’a pas tenue ses promesses. L’objectif “cloud” a été totalement raté, de même qu’un certain nombre d’API qui devaient être mises à jour (JCache en particulier).

Heureusement, un travail minimal a été réalisé sur les HTML5 et sur JMS 2, et nous avons eu la bonne surprise de voir l’intégration de Spring Batch dans la spécification. En 2013, nous n’en attendions pas moins !