Archives pour février, 2009

Premiers pas sur Wicket – Configuration

Préambule

Ca fait un petit moment (quelque chose comme 6 – 8 mois) que j’entends parler de Wicket.
Aujourd’hui, je décide de franchir le pas, et de voir ce que ça vaut vraiment…

Mais alors qu’est-ce que c’est que Wicket ?
Je pourrais faire un copier coller du site web officiel de l’outil, et dire ainsi :
With proper mark-up/logic separation, a POJO data model, and a refreshing lack of XML, Apache Wicket makes developing web-apps simple and enjoyable again. Swap the boilerplate, complex debugging and brittle code for powerful, reusable components written with plain Java and HTML.
Mais non, ce serait un peu trop facile !

Wicket est donc un projet de la communauté Apache correspondant ainsi à un framework de présentation, basé uniquement sur du Java et du HTML.

On se prépare

Qui n’est pas bien équipé ne pourra pas bien travailler !
Je jette tout d’abord un oeil sur les IDEs compatibles avec Wicket.
La page du site me propose ainsi des plugins pour les plus populaires des IDEs, à savoir Eclipse, NetBeans et IntelliJ.
Optant pour ce dernier, je regarde donc du côté de WicketForge.
Pour la configuration sur Eclipse, je laisse mon ami Jawher s’occuper des explications
Du côté Java, je reste sur mon Java 5, et un petit Maven 2.0.9.

On jette les bases

La première chose à faire, c’est de créer un nouveau projet sur IntelliJ.
Pour me faciliter la tâche, j’utilise l’archetype dédié à Wicket, qui me permet de créer la structure pour mon projet Wicket.

La commande Maven en ligne correspondante serait celle-ci :

mvn archetype:create -DarchetypeGroupId=org.apache.wicket -DarchetypeArtifactId=wicket-archetype-quickstart -DarchetypeVersion=1.3.5 -DgroupId=romain -DartifactId=wicket-test

Comme le précise le site de Wicket, ce dernier utilise obligatoirement slf4j qui est un logger (un peu comme log4j).
Pour utiliser log4j au sein de son projet, il suffit d’ajouter la dépendance vers slf4j-log4j12.
Cette dépendance est obligatoire pour toutes les versions Wicket depuis la 1.3.0

Mon pom.xml ressemble donc à ceci :

XML:

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 <a href="http://maven.apache.org/maven-v4_0_0.xsd">">http://maven.apache.org/maven-v4_0_0.xsd"></a>
    <modelVersion>4.0.0</modelVersion>
    <groupId>romain</groupId>
    <artifactId>wicket-test</artifactId>
    <packaging>war</packaging>
    <version>1.0</version>
    <dependencies>
        <!– Wicket Dependencies –>
        <dependency>
            <groupId>org.apache.wicket</groupId>
            <artifactId>wicket</artifactId>
            <version>${wicket.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.wicket</groupId>
            <artifactId>wicket-extensions</artifactId>
            <version>${wicket.version}</version>
        </dependency>
        <!– Logging Dependencies – LOG4J –>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.4.2</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.14</version>
        </dependency>
        <!–  JUnit for tests –>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.0</version>
            <scope>test</scope>
        </dependency>
        <!–  Jetty, used for web test –>
        <dependency>
            <groupId>org.mortbay.jetty</groupId>
            <artifactId>jetty</artifactId>
            <version>${jetty.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.mortbay.jetty</groupId>
            <artifactId>jetty-util</artifactId>
            <version>${jetty.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.mortbay.jetty</groupId>
            <artifactId>jetty-management</artifactId>
            <version>${jetty.version}</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <build>
        <resources>
            <resource>
                <filtering>false</filtering>
                <directory>src/main/resources</directory>
            </resource>
            <resource>
                <filtering>false</filtering>
                <directory>src/main/java</directory>
                <includes>
                    <include>**</include>
                </includes>
                <excludes>
                    <exclude>**/*.java</exclude>
                </excludes>
            </resource>
        </resources>
        <testResources>
            <testResource>
                <filtering>false</filtering>
                <directory>src/test/java</directory>
                <includes>
                    <include>**</include>
                </includes>
                <excludes>
                    <exclude>**/*.java</exclude>
                </excludes>
            </testResource>
        </testResources>
        <plugins>
            <plugin>
                <groupId>org.mortbay.jetty</groupId>
                <artifactId>maven-jetty-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    <properties>
        <wicket.version>1.3.5</wicket.version>
        <jetty.version>6.1.4</jetty.version>
    </properties>
</project>

Le projet créé par l’archetype a la structure suivante :

Le web.xml est constitué essentiellement par la définition du filtre de Wicket :

XML:

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee <a href="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"">http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"</a>
         version="2.4">
    <display-name>wicket-test</display-name>
    <!–
           There are three means to configure Wickets configuration mode and they are
           tested in the order given.
           1) A system property: -Dwicket.configuration
           2) servlet specific <init-param>
           3) context specific <context-param>
           The value might be either "development" (reloading when templates change)
           or "deployment". If no configuration is found, "development" is the default.
     –>
    <filter>
        <filter-name>wicket.wicket-test</filter-name>
        <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
        <init-param>
            <param-name>applicationClassName</param-name>
            <param-value>romain.WicketApplication</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>wicket.wicket-test</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

Au niveau du code source et des pages, il existe trois fichiers :

  • WicketApplication.java : cette classe est le point d’entrée de l’application, qui étend org.apache.wicket.protocol.http.WebApplication et défini principalement la méthode getHomePage(), qui retourne la classe Java gérant la page d’accueil de mon application.
  • HomePage.java est la classe Java gérant ma page d’acceuil. Elle étend org.apache.wicket.markup.html.WebPage
  • HomePage.html est la page d’acceuil, en version HTML.

Si l’on jette un oeil sur le fichier HomePage.html, on voit ceci :

HTML:

<html>
    <head>
        <title>Wicket Quickstart Archetype Homepage</title>
    </head>
    <body>
        <strong>Wicket Quickstart Archetype Homepage</strong>
        <br/><br/>
        <span wicket:id="message">message will be here</span>
    </body>
</html>

A priori, rien de particulier, à ceci près que le span contient un attribut wicket:id.

Premier test

On va maintenant démarrer le serveur.
L’archetype a eu la gentillesse de nous créer un test JUnit qui se charge en réalité de créer et démarrer un serveur Jetty.
On lance donc le serveur, et voici les logs :



INFO – log – Logging to org.slf4j.impl.Log4jLoggerAdapter(org.mortbay.log) via org.mortbay.log.Slf4jLog
>>> STARTING EMBEDDED JETTY SERVER, PRESS ANY KEY TO STOP
INFO – log – jetty-6.1.4
INFO – log – NO JSP Support for /, did not find org.apache.jasper.servlet.JspServlet
INFO – Application – [WicketApplication] init: Wicket core library initializer
INFO – RequestListenerInterface – registered listener interface [RequestListenerInterface name=IBehaviorListener, method=public abstract void org.apache.wicket.behavior.IBehaviorListener.onRequest()]
INFO – RequestListenerInterface – registered listener interface [RequestListenerInterface name=IBehaviorListener, method=public abstract void org.apache.wicket.behavior.IBehaviorListener.onRequest()]
INFO – RequestListenerInterface – registered listener interface [RequestListenerInterface name=IFormSubmitListener, method=public abstract void org.apache.wicket.markup.html.form.IFormSubmitListener.onFormSubmitted()]
INFO – RequestListenerInterface – registered listener interface [RequestListenerInterface name=IFormSubmitListener, method=public abstract void org.apache.wicket.markup.html.form.IFormSubmitListener.onFormSubmitted()]
INFO – RequestListenerInterface – registered listener interface [RequestListenerInterface name=ILinkListener, method=public abstract void org.apache.wicket.markup.html.link.ILinkListener.onLinkClicked()]
INFO – RequestListenerInterface – registered listener interface [RequestListenerInterface name=ILinkListener, method=public abstract void org.apache.wicket.markup.html.link.ILinkListener.onLinkClicked()]
INFO – RequestListenerInterface – registered listener interface [RequestListenerInterface name=IOnChangeListener, method=public abstract void org.apache.wicket.markup.html.form.IOnChangeListener.onSelectionChanged()]
INFO – RequestListenerInterface – registered listener interface [RequestListenerInterface name=IOnChangeListener, method=public abstract void org.apache.wicket.markup.html.form.IOnChangeListener.onSelectionChanged()]
INFO – RequestListenerInterface – registered listener interface [RequestListenerInterface name=IRedirectListener, method=public abstract void org.apache.wicket.IRedirectListener.onRedirect()]
INFO – RequestListenerInterface – registered listener interface [RequestListenerInterface name=IRedirectListener, method=public abstract void org.apache.wicket.IRedirectListener.onRedirect()]
INFO – RequestListenerInterface – registered listener interface [RequestListenerInterface name=IResourceListener, method=public abstract void org.apache.wicket.IResourceListener.onResourceRequested()]
INFO – RequestListenerInterface – registered listener interface [RequestListenerInterface name=IResourceListener, method=public abstract void org.apache.wicket.IResourceListener.onResourceRequested()]
INFO – RequestListenerInterface – registered listener interface [RequestListenerInterface name=IActivePageBehaviorListener, method=public abstract void org.apache.wicket.behavior.IBehaviorListener.onRequest()]
INFO – RequestListenerInterface – registered listener interface [RequestListenerInterface name=IActivePageBehaviorListener, method=public abstract void org.apache.wicket.behavior.IBehaviorListener.onRequest()]
INFO – Application – [WicketApplication] init: Wicket extensions initializer
INFO – WebApplication – [WicketApplication] Started Wicket version 1.3.5 in development mode
********************************************************************
*** WARNING: Wicket is running in DEVELOPMENT mode. ***
*** ^^^^^^^^^^^ ***
*** Do NOT deploy to your live server(s) without changing this. ***
*** See Application#getConfigurationType() for more information. ***
********************************************************************
INFO – log – Started SocketConnector@0.0.0.0:8080

Je me connecte donc à mon serveur, à l’adresse http://localhost:8080, et je vois le résultat suivant :

Je constate qu’effectivement Wicket a utilisé le fichier HomePage.html, mais le span donc le wicket:id était précisé a vu son contenu modifié par la classe Java HomePage.java.
C’est plutôt un bon début, non ?

Voilà un premier pas dans le mode Wicket.
Rendez-vous dans un prochain billet, pour des tests un peu plus poussés !

Start Slide Show with PicLens Lite PicLens

Sortie de Sonar 1.6

Voici deux jours que Sonar est sorti en version 1.6.

En plus des dfférents bugs corrigés sur cette version, nous trouvons trois nouveautés plutôt intéressantes :

  • gestion de seuils d’alertes. Il est ainsi possible d’être alerté dès que la couverture de tests baissent sous les 30%, si la complexité d’une classe excéde 40, etc.
  • amélioration de la gestion des profils de qualité. En plus de la configuration PMD et checkstyle, chaque profil est lié désormais à un ensemble d’alertes.
  • affectation des profils qualité à différents projets. Précédemment, un seul profil qualité était actif pour l’ensemble des projets. Désormais, il est possible de définir, pour chaque profil, quels sont les projets associés.

 Voici deux captures d’écran montrant le principe des alertes :

 

Lors de mon premier test de cette nouvelle version, j’ai obtenu différentes erreurs, en particulier celle-ci :

[INFO] [sonar-core:prepare]
[ERROR] Cannot execute the command org.codehaus.sonar:sonar-core-maven-plugin:1.6:prepare

java.lang.ClassCastException: java.lang.NoClassDefFoundError
        at org.picocontainer.lifecycle.ReflectionLifecycleStrategy.invokeMethod(ReflectionLifecycleStrategy.java:115)

        at org.picocontainer.lifecycle.ReflectionLifecycleStrategy.start(ReflectionLifecycleStrategy.java:89)
        at org.picocontainer.adapters.InstanceAdapter.start(InstanceAdapter.java:113)
        …

Après renseignement, il s’agirait d’un souci avec certaines dépendances présentes dans le repository Maven local. Le problème est effectivement parti après un nettoyage de ce dernier…

 

Start Slide Show with PicLens Lite PicLens