Sections

  1. Permiers pas
  2. Persistence
  3. La couche web
  4. Les tests
  5. Plugins

Migrer vers Grails 2

Il y a toujours certaines incompatiblités lors d'un changement de version majeur d'un framework. Ce document fera le tour des changements que vous aurez besoins d'effectuer pour migrer une application existante de Grails 1.3.x à Grails 2.0. Certains changements s'appliquent à tous les projets, d'autres non. La complexité de la migration dépend aussi des plugins déjà installés. Les plugins qui ont été testés avec Grails 2.0 (lors de sa sortie) apparaissent à la fin de ce guide.

Permiers pas

La première étape est de supprimer le répertoire 'target' de votre projet. Ensuite, avec Grails 2, lancez la commande suivante :


grails upgrade --force

Cette commande fera en sorte d'installer la dernière version de la définition des taglib JSP et, encore plus important, le dernier applicationContext.xml.

Le fichier web.xml a aussi été modifié, mais cela affecte seulement les projets qui ont un template web.xml dans le répertoire 'src/templates'. Si c'est votre cas, repérez les changements que vous y avez fait, exécutez de nouveau grails install-templates et, finalement, appliquez vos changements au nouveau web descriptor.

Si vous souhaitez utiliser la nouvelle console interactive (pourquoi vous ne le souhaiteriez pas ?), il vous faut préparer un peu plus d'espace heap et permgen pour votre application.


export GRAILS_OPTS="-Xmx700m -XX:MaxPermSize=384m"

Pour optimiser ces valeurs, vous pouvez utiliser la jconsole de la JDK pour voir combien de mémoire votre application consomme lorsque vous utilisez la console interactive.

Persistence

La couche de persistence a été énormément modifiée ces derniers temps, surtout à cause que GORM peut maintenant être utilisé avec plusieurs engins de persistence et pas seulement avec SQL et Hibernate. Tout de même, la plupart de vos modèles ne se verront que peu modifiés (si modification il y a).

Nouvelle base de données en mémoire

Plusieurs projets utilisent probablement l'ancienne base de données par défaut HSQLDB en développement. Grails 2 a changé pour H2 par défaut à la place. Si vous lancez votre application, vous verrez cet avertissement :


Database driver org.hsqldb.jdbcDriver for HSQLDB not found. Since Grails 2.0 H2 is now the default database. You need to either add the 'org.h2.Driver' class as your database driver and change the connect URL format (for example 'jdbc:h2:mem:devDb') in DataSource.groovy or add HSQLDB as a dependency of your application.

Comme ce message l'explique, vous pouvez résoudre ce problème de deux façons. La méthode la plus rapide est d'ajouter cette ligne au fichier BuildConfig.groovy :

…
grails.project.dependency.resolution = {
    …
    dependencies {
        runtime "hsqldb:hsqldb:1.8.0.10"
        …
    }
}

La version ci-dessus du pilote pour HSQLDB est fourni dans la distribution de Grails, vous n'aurez donc pas besoin de la télécharger depuis Internet. Si vous préférez migrer vers H2, modifiez le fichier DataSource.groovy pour utiliser le pilote de H2 ainsi que son URL de connection :

dataSource {
    driverClassName = "org.h2.Driver"

// In memory database url = "jdbc:h2:mem:devDb;MVCC=TRUE"

// File-based database //url = "jdbc:h2:prodDb;MVCC=TRUE" … }

Si vous utilisez cette méthode, vous n'avez pas besoin d'inclure le JAR de H2 en tant que dépendence explicite car il est inclu par la directive inherits("global").

Classes de domaine abstraites

Selon ce modèle :

Person est déclaré comme une classe abstraite. Avant Grails 2, ce modèle était persisté en deux tables séparées, une pour Employee et une autre pour Manager. Cela ne fait pas vraiment de sens car les deux modèles partagent des propriétés de la classe Person. Alors Grails 2 va maintenant créer une table unique Person que Employee et Manager vont utiliser.

Si vous avez des données basées sur le vieux modèle, ce changement brisera votre application. Plusieurs options s'offrent à vous :

  1. Migrer vos données vers le nouveau modèle avec une table partagée; ou
  2. Déplacer votre classe abstraite dans le répertoire 'src/groovy'.

La dernière de ces deux options est généralement la plus simple à effectuer.

Nom de propriété problématique

Quelques propriétés des classes de domaine posent problèmes pour différentes raisons :

Le problème avec environnement est fixé dans Grails 2.0.1. Les autres problèmes, les propriétés identiques au méthodes static injectées par GORM, seront fixés dans des versions futures.

La couche web

Grails 2 introduit beaucoup de nouvelles fonctionnalités aux controlleurs ainsi qu'aux autres parties de la couche web mais très peu de ces changements briseront votre code. Le plus grand changement est que les actions peuvent être déclarées comme des méthodes publiques et nous vous recommandons de le faire. Par contre, cela signifie que si vous avez déjà des méthodes publiques, elles seront considérées comme des actions - ce n'est probablement pas ce que vous désirez. Assurez-vous de modifier ces méthodes pour les mettre private ou protected.

Scaffolding et error view

Grails 2 introduit un nouveau scaffolding en HTML5 ainsi qu'une nouvelle 'error view'. Ces éléments fonctionnent très bien 'out-of-the-box' mais pas dans un projet migré. La façon la plus simple d'avoir ces éléments est de créer un nouveau projet avec Grails 2 et de copier les fichiers dans votre projet existant :


cp <path to new project>/web-app/css/main.css <path to existing project>/web-app/
cp <path to new project>/grails-app/views/error.gsp <path to existing project>/grails-app/views/

NB : Si vous avez modifié ces fichiers, la migration est un peu plus complexe. Vous devez réappliquer vos changements à ces nouveaxu fichiers. En fait, il est mieux de renommer 'main.css' en quelque chose d'autre (comme app.css) et l'utiliser pour vos propres vues. En d'autres mots, laissez 'main.css' pour le scaffolding.

Redirections

Afin de permettre au code de modifier la réponse après avoir effectuer une redirection, Grails a besoins d'outrepasser la méthode sendRedirect() du servlet standard. Ceci fait en sorte que redirect() est maintenant dépedant de la propriété de configuration grails.serverURL. Si cette propriété ne correspond pas à l'URL de votre application, les redirections ne fonctionneront plus.

La façon la plus simple afin d'éviter ce problème est de ne plus utiliser cette configuration sauf si vous en avez absolument besoin. Si vous l'utilisez (normalement dans un environnement de production) alors cette valeur correspond déjà à l'URL de votre application. Bref, cela affecte uniquement les environnements de développement qui utilisent une URL obsolète qui ne fonctionne pas.

Un autre problème causé par ce changement est que la méthode response.isCommitted() ne fonctionne plus pour déterminer s'il y a eut une redirection. À la place, il y a une nouvelle méthode request.isRedirected() que vous devrez utiliser - attention cette méthode s'appelle sur la propriété request et non sur response!

Negotiation de contenu

Avant la version 2, Grails utilisait le type de la requête pour faire sa négotiation de contenu. Par contre, le type de la requête est une mauvaise base pour déterminer le type de la réponse - c'est pour ça qu'a été créé le header Accept! Alors Grails 2 l'ignore maintenant. Cela peut briser votre usage de withFormat() si vous dépendez du type de la requête.

Si vous désirez effectuer quelque chose selon le type de la requête, alors utilisez simplement la méthode withFormat de la propriété request à la place :

request.withFormat {
    xml {
        // Do something for XML request content
    }
    json {
        // Do something for JSON request content
    }
}

AJAX tags + Prototype.js

Grails a fournit prototype.js par défaut pendant longtemps. Finalement, cela a été modifié : Grails 2 ne fournit plus de librairie Javascript. À la place, Grails 2 installe le plugin JQuery automatiquement en tant que dépendance de votre projet.

Si votre projet utilise les tags AJAX de Prototype.js, vous devrez installer le nouveau plugin Prototype en tant que dépendance.

Installation du plugin Resources

Le plugin Resources est une bonne façon de gérer les ressources web statiques comme les fichiers CSS et Javascript. Beaucoup de projets avant Grails 2 l'utilisent déjà. Si c'est le cas, faite attention car Grails 2 est resources-aware et modifie le comportement de <g:resource> et <g:javascript> si le plugin est installé.

Cela signifie en fait que vous devriez utiliser <r:layoutResources> dans toutes vos réponses web, sauf peut-être pour les réponses AJAX qui sont un peu plus complexe.

Nous ne vous recommandons pas d'utiliser du markup et du javascript dans vos réponses AJAX. Par contre, si vous le faite, utiliser <script> à la place de <g:javascript>.

Une dernière chose à propos des ressources : L'url /static est automatiquement créée pour déservir vos ressources. Alors si vous avez des règles de contrôle d'accès basées sur l'url, vous devrez les mettre à jour.

Les tests

Grails 2 vient avec un framework de test énormément amélioré, par contre, il est complètement incompatible avec l'ancien. L'ancien est toujours là donc vos tests existants vont encore fonctionner. Par contre, si vous souhaitez les mettre à jour, il va falloir les réécrire entièrement. Si vous optez pour ce scénario, jetez un coup d'oeil aux nouvelles annotations.

Plugins

Les versions des plugins suivants fonctionnent avec Grails 2 :

PluginVersionNotes
resources1.1.6 
spring-security-core1.2.7.1