Play! Framework
Play est un framework de développement web dans la sphère java, visant à offrir une productivité plus élevée aux développeurs de par sa simplicité et sa facilité d’accès. Il a beaucoup suscité l’engouement de la communauté au début de cette année, où il apparaissait comme un framework jeune mais prometteur et s’inspirant des bonnes idées observées dans d’autres frameworks comme Ruby On Rails. Ce billet a pour but de revenir sur ce framework un an après afin de (re)découvrir ses traits différentiant, de jeter un œil sur les évolutions que sa communauté a pu lui apporter depuis le début de l’annee ainsi que sur la roadmap prévue pour la version 1.1 qui sortira dans quelques semaines.
Tout d’abord, parlons de ses traits différentiant.
Play n’est pas un framework JEE
Si Play est un framework MVC basé sur la JVM, il n’est pas pour autant un framework JEE. En effet, il n’implémente pas la norme Servlet, puisqu’il ne se base pas sur un serveur d’application (JEE) mais sur un serveur HTTP simple appelé Apache Mina.
Qu’est-ce que cela change concrètement ? Et bien pas grand-chose. Votre application pourra générer un WAR classique, que vous pourrez déployer (en mode explosé uniquement) dans la plupart des serveurs d’application JBoss, Glassfish, Websphere, Jetty, Tomcat, etc. Le déploiement natif (sur Mina) est intéressant en développement et du point de vue des performances, tandis que le déploiement sur un serveur d'application classique apporte les avantages liés au packaging et à la gestion des versions en production.
Le plus important à signaler est l’architecture stateless du framework. En effet, et bien que la première version du framework était basée sur un serveur d’application classique, les HTTPSessions n’etaient pas utilisées. Dans un souci de cohérence, le framework a été refactoré en se basant sur le serveur Mina jugé suffisant pour les besoins des applications web.
Guillaume Bort, le créateur du framework, est longuement revenu sur ces considérations dans son blog personnel.
Le fait que Play ne soit pas basé sur un serveur JEE, vous privera de quelques fonctionnalités (rarement utilisées de nos jours) comme d'exposer des services en RMI. Mais tout ce dont vous avez besoin pour faire un site web est disponible dans Play, (via le serveur HTTP Mina).
Play et la compilation à la volée
Un aspect très intéressant et inédit du framework du point de la productivité des developpements, est sa méthode de compilation.
Le framework Play considère java comme un langage dynamique interprété, bien qu’il ne le soit pas. Il se base sur les .java et non sur les .class. De ce fait, il compile votre code à la volée au moment où vous effectuez une requête, et vous affiche le résultat de la compilation dans le navigateur. Le framework fait un travail sur les exceptions, de façon à ne pas afficher des stack traces longues, mais l’erreur finale (la stack trace reste disponible dans la console Play).
La plupart des modifications que vous apporterez à votre code ne vous demanderont pas de relancer le serveur. Cette fonctionnalité de hot deploy est très appréciée du point de vue développeur puisqu’elle ameliore la productivité.
Les captures d’écran suivantes montrent tout cela :
Une erreur dans la vue (.html) :
Une erreur dans un fichier .java :
Play et les tests
Le framework contient des classes qui vous aident à écrire des tests. Il fournit UnitTest, FunctionalTest et des tags Selenium pour du test d’interface. Cette nomenclature de tests rappelle fortement celle de Ruby On Rails.
Concrètement, quand vous lancez vos tests, un module de jeu et d’affichage des résultats dans le navigateur est chargé, et vous affiche le résultat de vos tests comme suit :
Première remarque tout de même, il est nécessaire de faire hériter nos classes de test de UnitTest ou FunctionalTest pour bénéficier de l’intégration au navigateur.
La classe FunctionalTest apporte en plus une aide pour l’écriture de requêtes http, de récupération des réponses et leur vérification. On peut par exemple écrire le test suivant :
Une deuxième remarque, les tests fonctionnels tels que imaginés par les créateurs du Framework correspondent plus à des tests d’intégration qu’à des tests fonctionnels, dans le sens ou ce sont des développeurs qui rédigeront ces tests (requêtes http, assertion des résultats), et non des experts fonctionnels. En terme de tests fonctionnels, l’intégration avec Fitnesse ou GreenPepper est possible mais l’automatisation de la génération du classpath Fitnesse n’est pas intégrée de base (le plugin Maven n’est pas utilisable nativement).
Play, le langage Java et la productivité
Play est basé sur le langage Java. Ceci constitue une force puisque c’est un langage répandu et maîtrisé par beaucoup de développeurs aujourd’hui.
Mais la force des frameworks productifs aujourd’hui comme Grails et Rails passe aussi par le langage lui-même, respectivement Groovy pour Grails et Ruby pour Rails, qui sont des langages dynamiques permettant une syntaxe plus concise, et plus pratique.
Play s’inspire de ces modèles, en proposant du sucre syntaxique permettant d’écrire par exemple :
Ou encore :
Mais on atteint vite les limites du langage Java. En effet, le prix de cette simplicité est la forte intrusion dans le code source puisque les classes du modèle doivent hériter de la classe play.db.jpa.Model pour des méthodes pratiques de JPASupport que sont findAll, save, etc.
Le même traitement s'applique aux contrôleurs qui doivent hériter de la classe play.mvc.Controller pour bénéficier des méthodes render ou redirect que l’on a l’habitude d’utiliser dans Grails par exemple.
Play et l’industrialisation des développements
Play a une communauté petite mais active.
La documentation disponible sur le site est globalement complète et à jour. L’intégration avec la plupart des IDEs est disponible et très fonctionnelle, ceci constitue un point très positif pour le framework. Un effort a été fait en termes de gestion de versions de la base de données, en se rapprochant du modèle Rails, grâce au module Migrate. Un module Play est un add-on développé par la communauté Play que l’on peut installer pour ajouter des fonctionnalités au framework.
De nouveaux modules sont toujours ajoutés par la communauté. C’est le cas par exemple du module d’intégration à Maven (publié en mars dernier), qui est venu combler l'absence de système de gestion des dépendances.
Malheureusement, l’intégration avec Maven s’arrête là. En ajoutant une dépendance dans le pom.xml de votre projet Play, vous la verrez bien apparaitre dans votre repository maven, mais aussi dans votre dossier lib de Play de façon automatique. Le module ne permet pas encore de retrouver toute la souplesse de compiler, tester, gérer vos versions ou releaser un projet Java avec Maven.
Il y a également un module Cobertura pour la couverture de tests unitaires dont les résultats peuvent être intégrés à Hudson.
En quelques mots, vos applications Play seront industrialisables via Hudson ou un autre outil d’intégration continue. Vous pourrez compiler, tester automatiquement, afficher la couverture de tests unitaires, générer des JAR et des WAR et les publier sur votre repository préféré. Mais cela vous demandera un effort supplémentaire par-rapport aux projets JEE standards.
Ceci constitue une des faiblesses principales du framework qui persiste jusqu’à aujourd’hui. Il est en effet dommage de devoir revenir sur les mêmes problématiques qui ont été adressées par un outil comme Maven (à titre d’exemple). Il est dommage de ne pas disposer d’un archetype Play, qui apporterait de la souplesse comme il en existe pour les frameworks JEE classiques. Enfin, il est dommage de ne pas retrouver une arborescence Maven standard et ne pas pouvoir profiter des plugins Maven disponibles, notamment pour la release et la gestion de la version. A noter que là aussi Play s’inspire de Rails, puisque l’arborescence Play est exactement la même.
Cependant, si les créateurs du framework ont fait le choix de ne pas se baser sur un outil comme Maven, une solution alternative serait en cours de développement par la communauté. A suivre donc…
L'évolution de Play depuis 1 an, et ce que va apporter la version 1.1
Il n’y a pas eu de sortie de versions majeures du cœur du framework. La 1.1 est toujours en développement et est prévue pour dans quelques semaines. Nous avons néanmoins assisté a l’apparition et à l’évolution de pas mal de modules Play, comme c’est le cas par exemple du plugin Maven (vs. paragraphe au dessus). C’est le cas aussi du plugin SCALA, apportant le support du langage SCALA dans le framework, et le module de scaffolding, apportant la fonctionnalité de génération automatique de contrôleurs et de vues à partir des classes du modèle.
La roadmap de la version 1.1 comprend principalement le support du langage SCALA par le compilateur et le support de sources de données NoSQL. Le cœur du framework sera encore une fois modifié pour remplacer Mina, qui n'évolue plus, par Netty. Un module Netty est deja disponible pour la version actuelle de Play.
Enfin, une initiative très intéressante de la communauté qui mérite d’être citée : Playapps. Cela rappelle fortement Heroku, plateforme cloud pour Ruby On Rails. Il s’agit donc d’une plateforme cloud visant à héberger des applications Play. C'est une opportunité intéressante de bénéficier d'un environnement d'intégration gratuit, simple à mettre en place et disponible rapidement. Initiative à suivre donc.
Ce qu’il faut retenir ?
Play est un framework web, et seulement web, simple, productif et facile d’accès. Il vient avec des idées intéressantes comme la compilation à la volée, la facilitation des tests d’intégration et des tests Selenium, une syntaxe un peu moins verbeuse par-rapport à Java et la volonté d’aller plus loin dans ce sens en intégrant des langages comme SCALA. Tout ceci apporte une souplesse et un confort pour le développeur. Il est intéressant donc de continuer à suivre les évolutions de ce framework, notamment en termes d’industrialisation des développements.