13 octobre 2009

IDE pour développement Grails

Si le développement d'une application Grails peut se faire avec la simple ligne de commande et un éditeur de texte comme TextEdit ou UltraEdit, les réalisateurs préfèrent utiliser un environnement qui leur facilite la vie et augmente leur productivité. Chez nous à Hydro-Québec ça veut dire, pour le monde Java, Eclipse ou IBM RAD, qui sont nos standards corporatifs.

 

Le support de Groovy et Grails dans Eclipse, et on peu présumer, dans RAD, est très rudimentaire et n'apporte pas de productivité au développeur. Selon nous, cette situation devrait éventuellement se corriger avec l'adoption grandissante de Grails dans l'industrie et avec l'intérêt de Guillaume Laforge[i]. C'est la raison pour laquelle, dans l'intérim, on a regarder NetBeans de NetBeans.org. Comme il est gratuit on s'est rapidement tourné vers lui pour nos développements Grails. L'intégration des commandes Grails est très intéressante, on obtient un bon grain de productivité par rapport à la ligne de commande et Eclipse.

 

Comme il s'agit d'un choix opérationnel, (pour le moment il n'est pas question d'adopter NetBeans pour le développement Java), NetBeans répondait bien à nos besoins Grails. Du moins, jusqu'à ce qu'on frappe un mur. En effet, il n'est pas possible de changer l'encoding des caractères des projets Grails, dans NetBeans par défaut les fichiers sont en UTF-8, pour se conformer à notre environnement de production, qui est en ISO 8859-1.

 

Comme on a actuellement des projets à livrer en Grails, il nous faut donc une autre solution. C'est ce qui nous a amener a considéré une autre alternative: IntelliJ de JetBrains.

 

Ce que l'on recherche d'un IDE Grails, ce sont les caractéristiques suivantes :

 

Caractéristique

Eclipse

NetBeans

IntelliJ

Lancer les commandes grails. Ex. create-app



˜

˜

Créer une classe de domaine

™

ž

˜

Créer les vues

™

ž

˜

Permet de spécifier encoding ISO-8859-1

 

ž

˜

Identification des erreurs de syntaxe, hilite syntaxe

™



˜

Code completion pour classes domaine et contoller

™

ž

˜

Code completion dans la pages gsp

™

™

˜

Code completion sur méthode dynamique

™

ž

˜

Intégration des tests unitaires (jUnit)

™

™

˜

Support débugging (breakpoint, step, watches…)

 

ž

˜

Support de gestionnaire de sources (CVS, SVN…)

ž

ž

˜

Visualisation UML des classes

™

™

˜

 

Clairement, IntelliJ se démarque par la qualité de l'intégration et le support de Grails et Groovy. On devra se pencher sérieusement sur ce produit en considérant le "big picture" car au-delà de la productivité brut, il faut considérer le prix des licences, l'intégration avec les autres outils de l'entreprise et la mobilité des ressources entre les équipes.

 

Pour démontrer le support de Grails/Groovy nous avons utilisé le scénario suivant :

(pour voir le vidéo suivre ce lien http://www.vimeo.com/7045498 )

 

  1. Créer nouveau projet
  2. Run de l'application (dans IntelliJ il faut configurer un environnement avant, la première fois).
  3. Créer un objet de domaine      "Blog"
  4. Ajouter un                               String titre
  5. Modifier le test unitaire
    1. Ajouter                       mockDomain(Blog) dans         Setup()
    2. Modif                          testSomething() pour                testBlogValide()
  6. Écrire le code du test
    1. def  b =  new Blog()    notez que NetBeans n'offre pas de code completion
    2. b.validate()
    3. assertFalse "Le blog devrait être valide", b.hasErrors()
  7. Exécuter les tests         NB : grails test-app

a.       IJ : ctrl shit F10           grails test

b.      IJ : ctrl shit F10           junit

  1. Ajouter un test pour     contenu
  2. Rouler le test : Red
  3. Corriger Blog en ajoutant         String contenu
  4. Rouler le test : Green
  5. Créer controller                       blog                 def scaffold = true
    1. Montrer que IJ groupe les classes par famille
  6. Rouler l'application
  7. Ajouter            def listxml = {} dans le controller
    1. Render Blog.list() as XML      montrer le code completion dans les 2                                     NB  class et méthode statique
    2. Montrer le import problem
  8. Rouler l'application
  9. Modifier pour render Blog.findAllByTitreLike dans IJ            
    1. Pour méthode dynamique
  10. Revenir à         render Blog.list() as XML
  11. Code completion dans les vues (gsp)
    1. Modifier index.gsp                  ${Blog.count()}
  12. Debugging
  13. Modifier          listxml
    1. Render Blog.get(params.id) as XML
  14. Insérer un breakpoint et un watch sur params
  15. Générer le diagramme UML du blog

 

Pour plus d'information sur les IDE Grails, consultez aussi : http://grails.org/IDE+Integration .

 

Dean Del Ponte a un excellent article sur les IDE (http://www.grailsblog.com/archive/show?id=10 ), cependant la version testée d'IntelliJ (8.1) est moins performante que celle que nous avons utilisée (8.1.3) et qui présente des améliorations importantes pour Grails 1.1.

 



[i]  Guillaume Laforge le 11 décembre 2008 suite à l'acquisition de G2One par SpringSource  :  "First of all, SpringSource's Eclipse team will join forces with our own Eclipse team to shift gears in the development of the Groovy/Grails Eclipse plugin. The lack of state of the art Groovy support in Eclipse can still be a limiting factor to adoption in the wild. However improved the plugin has gotten over the past year, lots of work is still needed to bring it on-par with expectations people have when working with their usual Java IDEs. So hopefully, in the coming months, you should see improved support of both Groovy and Grails in Eclipse."

19 mars 2009

Script et code du video sur Grails

Un menuisier à plus d’un outil dans son coffre. A l’inverse, quand on a seulement un marteau, tous les problèmes ressemblent à un clou. C’est un peu l’état de la situation pour notre développement Java dans les petits développements et à la limite pour les projets de moyennes envergures. Dans le but de garnir notre coffre à outils, nous en sommes à évaluer divers cadres logiciel (framework). Un des plus prometteurs est Grails (http://www.grails.org ), un framework inspiré de Rails, que j’ai beaucoup aimé, mais qui est un peu compliqué à introduire dans une grande entreprise en raison du langage sous-jacent : Ruby.

 

Grails utilise la même philosophie de « convention over configuration » que Rails, mais fonctionne dans un environnement Java (JEE) standard. Comme nous utilisons Tomcat et WebSphere comme environnement de déploiement, Grails est très intéressant. C’est cependant sa simplicité et sa rapidité de développement qui en font un outil de premier plan pour nos besoins.

 

Dans la suite du document nous allons bâtir une application simple de suivi d'un portefeuille de projet.

Un environnement de développement en 20 minutes

 

Pour débuter le développement, il s’agit d’installer le JDK le plus récent (1.6.0_12) et spécifier les deux variables d’environnement PATH et Java_Home et de vérifier que Java peu être invoqué à la ligne de commande.

 

java

 

Ensuite, on installe Grails et on ajuste le PATH et on spécifie le Grails_Home et on vérifie que Grails est correctement installé.

 

grails help

 

Pour les besoins de rapportage nous allons utiliser JasperReport. Pour créer les rapports nous installerons iReport.

 

Comme nous utiliserons la base de données HSQLDB pour la démo, il faut copier le driver HSQLDB  (1.0.8) de Grails dans celui de HSQLDB (1.0.7) afin que les deux utilisent la même version.

 

En incluant les temps de téléchargement, vous devriez être à pied d’œuvre en une vingtaine de minutes.

Une première page avec validations

 

Pour la majorité du développement nous allons utiliser une fenêtre de commande DOS.

 

Créez un nouveau répertoire pour l’application :

mkdir demos

 

Créez l’arborescence, le squelette, de la nouvelle application (appelons là « gest »)

grails create-app gest

 

Allez dans le nouveau répertoire

cd gest

 

Créez une classe pour l’entité de projet

grails create-domain-class projet

 

Avec un éditeur de texte ajoutez les attributs de la classe projet (dans /grails-app/domain) et sauvegarder les modifications.

 

String nom

String unite

Integer noProposition

String urlProposition

Integer mehari

 

A ce point ci nous avons une classe de « model » du pattern MVC (model-view-controller). Cet objet persistant peut déjà être utilisé par programmation. Nous allons cependant ajouter le contrôleur et la vue qui nous permettrons d’interagir avec la classe via une page web en trois ligne.

 

D’abord, créez le contrôleur :

grails create-controller projet

 

Avec un éditeur de texte modifier le code du contrôleur de projet (dans /grails-app/controller) et sauvegarder les modifications. Inscrivez :

 

def scaffold = Projet

 

Cette ligne de code va créer les vues du MVC de façon dynamique.

 

Il ne reste plus qu’à lancer l’application

grails run-app

 

Maintenant que l’application tourne, ouvrez le fureteur à l’adresse suivante, et ajouter un projet.

 

http://localhost:8080/gest

 

Voilà, une application fonctionnelle en quelques minutes!

 

Oui, mais notre travail n’est pas terminé. Nous allons d’abord ajoutez quelques validations. Modifiez la classe de domaine pour « projet ».

 

static constraints = {

   nom(blank :false, maxSize :10, unique:true)

   mehari(range:1..4)

   noProposition()

   urlProposition(url:true)

   unite()

}

 

Sauvegardez les modifications et actualisez la fenêtre du fureteur. Saisissez un nouveau projet sans nom de projet ou avec plus de 10 caractères de long.

 

On a créé une application fonctionnelle en une dizaine de minutes.

Ajouter une liste déroulante

Nos « projets » sont associés à un « marché ». Nous allons donc ajouter une nouvelle classe et son contrôleur (« marche ») et l’associer à la classe « projet ».

 

grails create-domain-class marche

 

Ajouter la propriété « nom » dans la classe  « marche »

 

String nom

 

Créez le contrôleur

grails create-controller marche

 

Modifiez le code du contrôleur de « marche » pour que la vue se gère automatiquement.

 

def scaffold = Marche

 

Sauvegarder les modifications.

 

Pour associer Projet et Marche, modifiez la classe Projet en ajoutant la propriété suivante :

 

Marche marche

 

Pour que ces modifications prennent effet il faut arrêter l’application et la redémarrer dans la fenêtre de commande.

 

Ctrl-C

O

grails run-app

 

Lorsque l’application est redémarrée, rafraîchissez la fenêtre du fureteur.

 

Ajouter deux marchés, puis un projet.

 

Notez la liste déroulante qui montre le nom de la classe et l’identifiant.

 

Comme ce n’est pas très joli, nous allons corriger la situation. Ajouter le code suivant à la classe « marche » (dans /grails-app/domain).

 

String toString() { return nom}

 

Notez qu’à chaque modification l’application est réinitialisée. Donc ajoutez deux marchés, puis un projet. Remarquez la liste déroulante.

 

Pour établir la relation dans l’autre sens, ajouter le code suivant à la classe de domaine « marche ».

 

static hasMany = [projet :Projet]

 

Pour s’assurer que les projets sont détruits lorsqu’on supprime un marché, ajoutez le code suivant à la classe du domaine « projet ».

 

static belongsTo = [marche :Marche]

 

Voilà une application fonctionnelle en quelques lignes de code. Pour savoir combien,  arrêter l’application, dans le fenêtre de commande et faites la commande suivante :

 

grails stats

 

Le tout nous aura pris une dizaine de minutes supplémentaires.

Modifier l’apparence

L’application que nous avons créée ne respecte pas nos normes visuelles. Pour les fins de la démonstration, j’ai modifié légèrement la feuille de style. Le but ici n’est pas montrer le produit final, mais simplement comment il est facile de modifier le look de l’application. Essentiellement, j’ai supprimé les images, changé la police de caractère et les couleurs.

 

Copier le fichier main.css dans /web-app/css

 

Lancer l’application pour voir l’effet du changement.

grails run-app

 

Grails supporte divers type de données, pour en faire la démonstration, ajoutez les propriétés suivantes à la classe de domaine « projet ».

 

Boolean implicationDpas

Date dateDeDemande

 

Dans le fureteur notez comment les libellés sont construits.

 

Vous avez remarqué que l’application « perd » ses données à chaque redémarrage, déclenché par les modifications que nous apportons au code. La raison de ce comportement est simple. Par défaut, en développement, Grails utilise une base de données HSQLDB mémoire qui est en mode de recréation. Pour rendre les données persistantes entre les redémarrages, modifiez le fichier de configuration (/grails-app/conf/DataSource).

 

dbCreate = "update"

url = "jdbc:hsqldb:file:devBD"

 

Grails peu utiliser toutes les bases de données que Hibernate supporte car sous Grails c’est ce composant qui est utilisé. Dans le même ordre d’idée, on trouve aussi le framework Spring sous le capot. Deux composants qui ont fait leurs preuves dans les grandes entreprises.

 

Un autre petit dix minutes bien utilisé.

Rapportage et recherche

Nous allons maintenant ajouter un rapport à la page de liste de projet. Pour ce faire nous utiliserons JasperReport qui est fournit en plugin. Pour l’installer :

 

grails install-plugin jasper

 

Pour modifier la vue de liste de projet, il faut avoir le code. Actuellement, il est généré dynamiquement à l’aide du « scaffolding » de Grails.

 

grails generate-all projet

 

A la fin de la page de liste, ajouter le tag suivant :

 

<g :jasperReport jasper= «ListeProjet » format= « PDF » name= « Rapport » />

 

Créez un rapport avec IReport nommé ListeProjet.jrxml et sauvegardé dans le répertoire :

 

/web-app/reports/

 

Pour ajoutez une recherche à la page de liste, modifiez le code de list.gsp (en haut de la liste) pour ajouter :

 

<g:form action="search" method="post" >

     <div class="dialog">

          <table>

                <tr class="prop">

                     <td class="name">

                          <label for="nom">Nom de projet</label>                       

                     </td>

                </tr>

                <tr class="value">

                     <td class="name">

                          <input type="text" name="nom" value=""/>                     

                     </td>

                </tr>

          </table>

          <div class="buttons">

                <input type="submit" value="Rechercher"/>

                <g:link action="list">Tout afficher</g:link>

          </div>

     </div>

</g:form>

 

Ensuite il faut modifier le contrôleur de Projet afin d'ajouter l'action "search" et modifier "list" pour passer le critère de recherche via un flash.

 

def search = {

     flash.nom = params.nom

     redirect(action:list)

}

 

def list = {

     if (!flash.nom)

          [projetInstanceList: Projet.list(params), projetInstanceTotal:Projet.count()]

     else

          [projetInstanceList: Projet.findAllByNomLike("%" + flash.nom + "%"), projetInstanceTotal:Projet.count()]

}

 

 

Il ne reste qu'a le déployer sur notre environnement de test

 

grails war

14 mars 2009

Démonstration de Grails

Depuis deux semaines j'explore avec succès le framework Grails, pour le développement web rapide. Pour vous faire partager l'expérience j'ai monté une série de courtes démo de 5 minutes qui montre comment développer avec Grails.

Après avoir installer je JDK de java et downloadé Grails, (une vingtaine de minutes avec l'installation) on démarre le développement. En cinq minutes on va avoir une application web!


Introduction à Grails from jean desbiens on Vimeo.

 Dans le prochain 10 minutes on ajoute une relation à notre principale entité.


Ajout d'une relation from jean desbiens on Vimeo.

 Afin de respecter plus les normes de notre entrepise on change la feuille de style CSS de l'application.


Modification du look de l'application grails from jean desbiens on Vimeo.

On ajoute maintenant un rapport PDF avec JasperReport.


Rapportage dans Grails from jean desbiens on Vimeo.

Finalement on ajoute une fonction de recherche et on package le tout pour le déploiement.


Recherche dans Grails et préparation du déploiement from jean desbiens on Vimeo.