lundi 2 août 2010

Accélérer le développement d'applications Vaadin avec Maven et Jetty

Cet article applique les principes décrits dans l'article "Accélérer le développement d'applications web Java avec Maven" aux applications web utilisant le framework Vaadin.


Présentation

Vaadin est un framework permettant de réaliser facilement des applications web riches. Il est construit sur le framework GWT.

Le principal avantage de Vaadin réside dans la génération des pages (ou écrans) de l'application. Ces derniers sont réalisés uniquement via du code Java, à la manière d'une interface Swing. Vaadin est packagé avec un ensemble de thèmes satisfaisant la plupart des besoins.


Objectif

On se propose d'accélérer le développement des applications utilisant Vaadin en mettant en place un rechargement dynamique des classes Java.

Comme dans le précédent article, ce tutoriel se focalisera sur l'utilisation de l'outil de build Maven conjointement au serveur d'application Jetty.


Etape 1 - Création du module Maven

Une fois de plus, la commande mvn archetype:generate se révèle très pratique pour mettre en route rapidement un projet Maven utilisant Vaadin.

$ mvn archetype:generate

Dans la liste des modèles de projet proposés, on note la présence du modèle "vaadin-archetype-clean". C'est ce dernier qui servira à générer un module de test Dans mon cas, il porte le numéro 7.

Choose a number : 7
Choose version : 1.3.0
Define value for property 'groupId': fr.pingtimeout
Define value for property 'artifactId': maven-vaadin
Define value for property 'version': 1.0-SNAPSHOT
Define value for property 'package': fr.pingtimeout

Le projet "maven-vaadin" est maintenant créé. Il contient une application basique utilisant Vaadin et affichant un bouton "Click Me".

On peut vérifier que le module contient bien les fichiers attendus.

$ cd maven-vaadin
$ tree.
|-- pom.xml
`-- src
    `-- main
        |-- java
        |   `-- fr
        |       `-- pingtimeout
        |           `-- MyVaadinApplication.java
        `-- webapp
            |-- META-INF
            |   |-- MANIFEST.MF
            |   `-- context.xml
            `-- WEB-INF
                `-- web.xml

Etape 2 - Activation du rechargement automatique

Cette fois, le plugin Jetty est déjà présent dans le fichier pom.xml. Toutefois, il doit être sensiblement modifié.

Dans le pom du module, le paramètre scanIntervalSeconds a pour valeur '0'. Un commentaire dans le fichier indique d'ailleurs que cette valeur désactive le rechargement automatique des classes.
Il faut donc changer la valeur du paramètre scanIntervalSeconds (par exemple, en spécifiant un scan toutes les secondes).

<scanIntervalSeconds>1</scanIntervalSeconds>

Etape 3 - Définition des ressources

Le chemin vers les ressources du projet sont définies par le paramètre code>resourcesAsCSV. Ce paramètre spécifie qu'elles sont situées dans le dossier /src/main/webapp et dans le dossier ${project.build.directory}/${project.build.finalName}. Dans mon cas, ceci équivaut au dossier /target/maven-vaadin-1.0-SNAPSHOT/.

Ce paramétrage pose un problème pour le rechargement automatique :

  • les classes recompilées sont situées dans le dossier ${project.build.outputDirectory} - dossier (1)
  • les classes initialement construites avec le war sont situées dans le dossier ${project.build.directory}/${project.build.finalName}/WEB-INF/classes/ - dossier (2)

En cas de modification d'un fichier .java, Jetty relance la compilation dans le dossier (1) mais n'en tient pas compte car les anciennes classes sont toujours dans le dossier (2).

Pour résoudre ce problème, il suffit de donner une nouvelle valeur au paramètre resourcesAsCSV :

<resourcesAsCSV>src/main/webapp,${project.build.directory}/${project.build.finalName}/WEB-INF/lib</resourcesAsCSV>

Seules les librairies de l'application seront désormais accédées en tant que ressources.

Etape 4 - Tests

Le serveur peut désormais être lancé via la commande :

$ mvn jetty:run

Premier lancement, premier échec. L'erreur suivante est générée par Jetty :

[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Failed to configure plugin parameters for: org.mortbay.jetty:maven-jetty-plugin:6.1.25

Cause: Setter org.mortbay.resource.ResourceCollection.setResourcesAsCSV( java.lang.Class ) threw exception when called with parameter 'src/main/webapp,/home/pingtimeout/Projects/maven-vaadin/target/maven-vaadin-1.0-SNAPSHOT/WEB-INF/lib': java.lang.IllegalArgumentException: file://home/pingtimeout/Projects/maven-vaadin/target/maven-vaadin-1.0-SNAPSHOT/WEB-INF/lib is not an existing directory.

Contrairement au précédent tutoriel, il est obligatoire de spécifier la cible "package", faute de quoi Jetty ne peut pas trouver le dossier ${project.build.directory}/${project.build.finalName}/WEB-INF/lib, car ce dernier n'existe pas.


Lancer le serveur avec la commande :

$ mvn clean package jetty:run

Le serveur est correctement démarré, il est possible de consulter l'application à l'adresse :

http://localhost:8080/maven-vaadin/
.

[INFO] Started Jetty Server
[INFO] Starting scanner at interval of 1 seconds.

Aucune opération supplémentaire n'est requise pour que Jetty prenne directement en compte les modifications effectuées aux fichiers Java.

Modifier le fichier MyVaadinApplication.java pour y ajouter un bouton.

public void init() {
        window = new Window("My Vaadin Application");
        setMainWindow(window);
        window.addComponent(new Button("Click Me"));
        window.addComponent(new Button("Click Pingtimeout"));
}

Relancer une simple compilation des classes Java du projet

$ mvn compile

Des que le fichier est recompilé, Jetty recharge automatiquement les classes de l'application web.

[INFO] Restart completed at Mon Aug 02 14:04:51 CEST 2010

Rafraîchir le navigateur internet pour constater que la modification a été prise en compte.

Epilogue

Le plugin Jetty pour Maven se révèle d'une grande efficacité. Moyennant quelques paramètres, il est possible de lui faire recharger dynamiquement des classes Java dans des applications complexe (war avec de nombreuses librairies externes).

Des problèmes à la mise en place du plugin ? Des améliorations à apporter à ce tutoriel ? Voyons tout ça dans les commentaires !

dimanche 1 août 2010

Accélérer le développement d'applications web Java avec Maven

Lorsqu'une application web (war) est développée avec Maven, elle doit être re-déployée sur un serveur d'application pour être testée, même quand elle ne contient que des modifications de forme. En utilisant le plugin Jetty pour Maven, il est possible d'effectuer un rechargement dynamique des JSP de manière transparente.

Présentation

Le développement d'une application J2EE est généralement découpé en plusieurs couches (application n-tiers) :
  • La couche de présentation ne contient que les écrans de l'application et ne gère aucune logique métier
  • Les couches sous-jacentes contiennent la logique métier, le modèle de données de l'application ainsi que la liaison avec un éventuel SGBD
L'outil de build Maven permet de séparer proprement ces différentes couches en un projet dit multi-modules. Dans ce cas, le module contenant les écrans est packagé sous la forme d'une application web java (war) et contient tous les modules du projet.
Note : le cas des ear n'est pas pris en compte dans cet article.
Un problème fréquent consiste à effectuer des modifications de forme (par exemple, la mise en page de l'application) et à vouloir s'assurer que ces modifications sont conformes au résultat attendu. Il faut alors reconstruire toute l'application web et la redéployer sur un serveur d'application. On embarque alors inutilement toutes les couches sous-jacentes.

Le plugin Jetty pour Maven

Parmi les plugins disponibles pour Maven, on note la présence d'un serveur d'application à part entière : Jetty. Ce plugin permet de lancer un serveur J2EE sur l'application web générée. Il permet également de prendre directement en compte les modifications faites sur les fichiers du module.

Etape 1 - Création d'un projet Maven

Commençons par créer un projet d'application web avec Maven. Exécuter la commande suivante : $ mvn archetype:generate
Dans la liste des modèles de projet proposés, on note la présence du modèle "maven-archetype-webapp (An archetype which contains a sample Maven Webapp project.)". Dans mon cas, il porte le numéro 66.
Choose a number : 66
Choose version : 1.0
Define value for property 'groupId': fr.pingtimeout
Define value for property 'artifactId': maven-webapp
Define value for property 'version': 1.0-SNAPSHOT
Define value for property 'package': fr.pingtimeout
Le projet "maven-webapp" est maintenant créé. Il contient un seul fichier JSP et affiche le très célèbre "Hello World".
On peut vérifier que le module contient bien les fichiers attendus.

$ cd maven-webapp
$ tree
.
|-- pom.xml
`-- src
    `-- main
        |-- resources
        `-- webapp
            |-- WEB-INF
            |   `-- web.xml
            `-- index.jsp

Etape 2 - Ajout du plugin Jetty au module

Le plugin Jetty n'est pas encore utilisable à ce stade. Modifier le fichier pom.xml en ajoutant, dans la section "build", les lignes suivantes :
<plugins>
    <plugin>
        <groupId>org.mortbay.jetty</groupId>
        <artifactId>maven-jetty-plugin</artifactId>
    </plugin>
</plugins>
La section "build" doit donc être la suivante :
<build>
    <finalName>maven-webapp</finalName>
    <plugins>
        <plugin>
            <groupId>org.mortbay.jetty</groupId>
            <artifactId>maven-jetty-plugin</artifactId>
        </plugin>
    </plugins>
</build>
Jetty peut maintenant être utilisé dans le module avec la commande : $ mvn jetty:run
Note : si le projet n'est pas compilé, la cible "jetty:run" passera automatiquement les phases de compilation et de test.

Etape 3 - Premier et dernier test

Après avoir lancé le serveur, il est possible de consulter le résultat de la JSP à l'adresse : http://localhost:8080/maven-webapp/
Aucune opération supplémentaire n'est requise pour que Jetty prenne directement en compte les modifications effectuées aux fichiers JSP.
Modifier le fichier index.jsp afin d'y ajouter un message, par exemple :
<html>
  <body>
    <h2>Hello World!</h2>
    <hr/>
    <h3>
      <% out.println(";-)"); %>
    </h3>
  </body>
</html>
Rafraîchir le navigateur internet pour constater que, même sans recompilation, la modification a été prise en compte.

Et les frameworks dans tout ça ?

Jetty peut également redéployer des applications plus lourdes, notamment celles qui utilisent des frameworks comme Struts ou Vaadin. Ce point fera l'objet d'un prochain article.


Un moyen encore plus simple de faire du rechargement dynamique ? Des remarques sur ce tutoriel ? N'hésitez pas à vous exprimer dans les commentaires.

dimanche 13 juin 2010

How to install Bonita on a Glassfish server with an Oracle database

This article is the english translation of Installer Bonita sur un serveur Glassfish avec une BDD Oracle


According to the official documentation, Bonita runtime and user experience can only be installed on JBoss or Tomcat servers. With little patience, those components can be deployed on Glassfish servers.


Introduction to Bonita

Bonita is an open-source workflow solution supported by the BPM company BonitaSoft.

The Bonita solution combines :

  • A standalone process design studio (the Bonita Studio)
  • A BPM engine (the Runtime)
  • A graphical user interface (the Bonita User Experience - BUE)

Goal

The goal of this tutorial is to install the runtime and the BUE on a Glassfish v2.1.1 server. The runtime will use a remote Oracle 10g database (XE). The Bonita Studio will be installed on the administrator's computer.

Process users will connect to the User Experience from a remote computer (WinXP / Firefox). So will the administrator.
The operating system installed on the application and database servers is CentOS 5.5.

In this tutorial, the application server's hostname is bonita.localdomain. The database server's hostname is database.localdomain


Note: this guide only contains information related to the appplication server's configuration. For instance, DBMS installation won't be covered in this article.


Requirements

  • Bonita Studio has already been installed on the administrator's computer
  • Oracle DBMS has already been installed on the database server
  • Glassfish is installed on the application server
  • Ant is installed on the application server

Step 1 - Export the engine

Start Bonita Studio, then click on "Process > Export application".

Check the "Export UserXP" and "All UserXP" checkbox
Check the "Export runtime" checkbox
Check the "Extract selected war libraries {...] in a common folder [...]"
Don't select any process in the process list
Select a location (for instance: /home/pingtimeout/bonita_application.zip)

A file named bonita_application.zip is created in the specified folder.

Unzip this file (e.g. in /home/pingtimeout/bonita_application/). The newly created folder now contains these elements:

  • common-war-lib
  • conf
  • runtime
  • wars
  • INSTALL.txt

Bonita UserXP and Runtime are now ready to be installed.


Step 2 - Create and initialize the databases

Note : in this tutorial, the databases "core" and "history" are stored on the same Oracle instance. However, they could be separated on two different instances.


Create two db users named CORE and HISTORY.

In the bonita_application folder, edit the file runtime/conf/hibernate-core.properties. Change the following parameters:

hibernate.dialect                 org.hibernate.dialect.Oracle10gDialect
hibernate.connection.driver_class oracle.jdbc.OracleDriver
hibernate.connection.url          jdbc:oracle:thin:@database.localdomain:1521:XE
hibernate.connection.username     CORE
hibernate.connection.password     CORE


Edit the file runtime/conf/hibernate-history.properties. Change the following parameters:

hibernate.dialect                 org.hibernate.dialect.Oracle10gDialect
hibernate.connection.driver_class oracle.jdbc.OracleDriver
hibernate.connection.url          jdbc:oracle:thin:@database.localdomain:1521:XE
hibernate.connection.username     HISTORY
hibernate.connection.password     HISTORY


Add the Oracle JDBC driver in runtime/lib/server/


Use ant to create and initialize the core db.
$ ant init-db
Choose the following configuration: hibernate-configuration:core


Use ant to create and initialize the history db.
$ ant init-db
Choose the following configuration: hibernate-configuration:history


The databases are now created and initialized.


Step 3 - Prepare a Glassfish domain

Note : $GLASSFISH_HOME is an environment variable that contains the absolute path to the bonita home directory (on my server : /opt/glassfish/)


Create a glassfish domain named "bonita"
$ asadmin create-domain --adminuser admin --portbase 24000 bonita

Enter the admin password and the master password for this domain to be created.


Copy all files from bonita_application/common-war-lib/ in $GLASSFISH_HOME/domains/bonita/lib/
$ cp bonita_application/common-war-lib/* $GLASSFISH_HOME/domains/bonita/lib/


Copy all files from bonita_application/runtime/lib/server/ in $GLASSFISH_HOME/domains/bonita/lib/
$ cp bonita_application/runtime/lib/server/* $GLASSFISH_HOME/domains/bonita/lib/


Copy all files from bonita_application/runtime/conf/ in $GLASSFISH_HOME/domains/bonita/config/
$ cp bonita_application/runtime/conf/* $GLASSFISH_HOME/domains/bonita/config/


Start the domain
$ asadmin start-domain bonita


The "bonita" glassfish domain is now started.


Step 4 - Install Bonita on Glassfish

Finally, bonita.war may now be uploaded on the application server.


On your domain's administration console (e.g. http://bonita.localdomain:24048/), click on "Web Application" menu item
In the application list, click on "Deploy"


In the field "Packaged file to be uploaded to the server", select bonita_application/wars/bonita.war
Enter "bonita" as application name
Click on "Ok"


Bonita is now installed on your server.
To access the BUE, click on the "Launch" button in the deployed applications list.

Did you run into problems during the installation, or think this article can be improved ? Let's hear about it in the comments. :-)


Enjoy !

dimanche 6 juin 2010

Installer Bonita sur un serveur Glassfish avec une BDD Oracle

Cet article est également disponible en anglais : How to install Bonita on a Glassfish server with an Oracle database


A l'heure actuelle, la documentation de Bonita ne permet d'installer le runtime et le portail que sur les serveurs JBoss et Tomcat. Avec un peu d'astuce, il est possible de les installer sur un serveur Glassfish.


Présentation de Bonita

Bonita est un moteur de workflow opensource soutenu par la société BonitaSoft.

L'outil "Bonita" est composé de trois éléments :

  • Le Studio Bonita, application autonome qui permet de modéliser graphiquement des processus d'entreprise.
  • Un moteur BPM (le runtime) qui gère toute la logique métier inhérente aux processus (changement d'état, transfert de messages, ...).
  • Un portail, appelé Bonita User Experience (BUE), permettant à chaque utilisateur d'exécuter les processus définis dans le Studio.

Objectif

On se propose d'installer le runtime et la BUE sur un serveur Glassfish v2.1.1. Le runtime devra être interfacé avec une base de données Oracle 10g (XE) hébergée sur une autre machine. Le studio Bonita sera, quand à lui, installé sur le PC d'un administrateur.

Nos utilisateurs se connecteront depuis un poste distant équipé de Windows XP et de Firefox.
L'administrateur utilisera un poste également équipé de Windows XP
Les deux serveurs utilisés (le serveur d'application et le serveur de base de données) seront tous deux sous CentOS 5.5.

Dans ce guide, le serveur d'application répond au nom de domaine bonita.localdomain. Le serveur de base de données répond, quant à lui, au nom de domaine database.localdomain


Note : Le but de ce guide est de présenter l'installation du runtime de manière simple. On ne s'intéressera donc qu'à la configuration du serveur d'application.


Pré-requis

  • Le studio Bonita est déjà installé et utilisable sur le poste administrateur
  • Le SGBD Oracle est opérationnel et une instance de base de données "XE" existe
  • Glassfish est opérationnel sur le serveur d'application
  • Ant est installé sur le serveur d'application

Etape 1 - Exporter le moteur

Démarrer le studio Bonita puis, dans le menu "Processus" cliquer sur "Exporter l'application".

Cocher les cases "Exporter la UserXP" et "Toute la UserXP"
Cocher la case "Exporter le moteur"
Cocher la case "Extraire les librairies des war dans un dossier commun"
Dans la liste des processus, décocher les processus éventuellement sélectionnés.
Choisissez un dossier pour l'export (par exemple : /home/pingtimeout/)

Un fichier bonita_application.zip sera créé dans le dossier spécifié.

Dézipper ce fichier (par exemple dans /home/pingtimeout/bonita_application/), le dossier cible contient les éléments suivants :

  • common-war-lib
  • conf
  • runtime
  • wars
  • INSTALL.txt

Les composants Runtime et UserXP sont maintenant prêts à être installés.


Etape 2 - Création et initialisation des bases de données

Note : dans mon cas, je choisis de stocker les bases de données "core" et "history" sur la même instance de base de données. Il aurait été possible de les séparer sur deux instances distinctes.


Créer deux utilisateurs (CORE et HISTORY) sur l'instance Oracle.

Se rendre dans le dossier bonita_application créé à l'étape précédente et modifier le fichier runtime/conf/hibernate-core.properties afin qu'il contienne les valeurs suivantes :

hibernate.dialect                 org.hibernate.dialect.Oracle10gDialect
hibernate.connection.driver_class oracle.jdbc.OracleDriver
hibernate.connection.url          jdbc:oracle:thin:@database.localdomain:1521:XE
hibernate.connection.username     CORE
hibernate.connection.password     CORE


Modifier le fichier runtime/conf/hibernate-history.properties afin qu'il contienne les valeurs suivantes :

hibernate.dialect                 org.hibernate.dialect.Oracle10gDialect
hibernate.connection.driver_class oracle.jdbc.OracleDriver
hibernate.connection.url          jdbc:oracle:thin:@database.localdomain:1521:XE
hibernate.connection.username     HISTORY
hibernate.connection.password     HISTORY


Ajouter le driver Oracle JDBC dans le dossier runtime/lib/server/


Exécuter la commande suivante :
$ ant init-db
Utiliser la configuration : hibernate-configuration:core


Exécuter la commande suivante :
$ ant init-db
Utiliser la configuration : hibernate-configuration:history


Les bases de données sont créées et initialisées.


Etape 3 - Préparation d'un domaine Glassfish

Note : $GLASSFISH_HOME représente le répertoire d'installation de Glassfish (dans mon cas, il s'agit de /opt/glassfish/)


Créer un domaine "bonita" dans glassfish
$ asadmin create-domain --adminuser admin --portbase 24000 bonita

Saisir un mot de passe pour l'administrateur et un mot de passe de sécurité générale puis valider


Copier tous les fichiers du répertoire bonita_application/common-war-lib/ dans le dossier $GLASSFISH_HOME/domains/bonita/lib/
$ cp bonita_application/common-war-lib/* $GLASSFISH_HOME/domains/bonita/lib/


Copier tous les fichiers du répertoire bonita_application/runtime/lib/server/ dans le dossier $GLASSFISH_HOME/domains/bonita/lib/
$ cp bonita_application/runtime/lib/server/* $GLASSFISH_HOME/domains/bonita/lib/


Copier tous les fichiers du répertoire bonita_application/runtime/conf/ dans le dossier $GLASSFISH_HOME/domains/bonita/config/
$ cp bonita_application/runtime/conf/* $GLASSFISH_HOME/domains/bonita/config/


Démarrer le domaine
$ asadmin start-domain bonita


Le domaine Glassfish est correctement paramétré et il est démarré.


Etape 4 - Installer Bonita sur Glassfish

Dernière étape, il faut maintenant installer le fichier bonita.war sur le serveur d'application.


Se connecter à l'interface d'administration du domaine (dans mon cas, http://bonita.localdomain:24048/)
Dans le menu de gauche, cliquer sur "Application Web".
Dans la liste des applications, cliquer sur le bouton "Déployer"
Saisir "bonita" dans le nom de l'application


Sélectionner le fichier bonita_application/wars/bonita.war dans le champ "Fichier de package à télécharger sur votre serveur"
Cliquer sur le bouton "Ok"


Bonita est maintenant installé sur le serveur.
Pour y accéder, dans la liste des applications web déployées, cliquer sur le lien "Lancer" de la ligne "Bonita".

Des soucis à l'installation ? Des points à améliorer ? N'hésitez pas à laisser un commentaire :-)


Enjoy !

dimanche 9 mai 2010

Bienvenue sur Ping Timeout.fr !

Enfin un site tout beau, tout neuf, il était temps !

Cher visiteur(trice), soyez le(la) bienvenu(e).

Vous trouverez ici des informations relatives aux projets qui me tiennent à cœur. Au menu, cette année :
* l'informatique
* la musique

Sans doute y aura-t-il quelques réflexions sur les problèmes de tous les jours, les méthodes de travail que j'ai pu rencontrer et ce que j'en retire.

Bonne lecture.

P. L.