Développement de Portlets

Ce document propose quelques règles de façon à homogénéiser les développements de Portlets.


Mathieu  LARCHET 

Dates de modification
Revision 1.0 1 mars 2006
1. Fichiers 'build' pour démarrer un projet
1.1. build.properties
1.2. build.xml
2. Tâches ANT
3. Organisation des répertoires
4. Pools de connexions
5. Contenu statique

1. Fichiers 'build' pour démarrer un projet

L'environnement de développement est sensiblement le même que celui d'un canal uPortal.

De façon à avoir des Portlets qui se compilent / déploient de façon identique, voici un fichier de configuration ANT pouvant servir de base commune à tous les développements :

1.1. build.properties

Comme pour les canaux, il est composé de deux parties, l'une réservée au développeur, l'autre à la personne qui le déploie.

Voici les différentes propriétés à configurer pour l'administrateur système :

Voici les différentes propriétés à configurer pour le développeur :

Voici les propriétés utilisées pour la génération de la documentation de la Portlet au format DocBook :

1.2. build.xml

Ce fichier propose un ensemble de tâches ANT pouvant servir de base à n'importe quelle Portlet. Un développeur peut choisir d'étendre celles-ci afin d'avoir des options spécifiques. Par exemple avec Spring, il est parfois nécessaire d'effectuer des changements dans les fichiers de configuration au moment du déploiement ou de la construction du WAR.

Le seul paramètre à modifier dans ce fichier (hormis une personnalisation plus poussée) est le nom projet indiqué dans la première ligne.

2. Tâches ANT

Voici un bref descriptif des tâches ANT et de leur utilité :

3. Organisation des répertoires

Pour commencer un nouveau projet, il suffit de placer les fichiers build.xml et build.properties, de les configurer et de lancer la tâche ANT prepare. Une arborescence est alors créée qui ressemble à quelques exceptions près à celle d'un canal uPortal.

Voici dans le détail les différents dossiers qui sont créés :

4. Pools de connexions

Tout comme les canaux uPortal, les Portlets ont parfois besoin d'accéder à une base de données. Il est possible de laisser le soin à Tomcat de gérer un pool de connexions pour une Portlet de la même façon que pour le portail puisqu'une Portlet est un contexte Java à part entière. Toutefois, il est beaucoup plus intéressant de pouvoir partager ce pool entre les deux applications.

Voici comment est défini un pool dans le contexte du portail :

<Context path="/uPortal" docBase="/home/uPortal/webapps/uPortal" crossContext="true">
  <Resource name="jdbc/MonPool" auth="Container" type="javax.sql.DataSource"
            username="user" password="password"
            driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://mysql.univ.fr/mabase"
            maxActive="100" maxIdle="30" maxWait="10000" />
  ...
</Context>

On va déplacer la définition de ce pool dans les déclarations globales JNDI et y faire référence à la fois depuis le contexte du portail et depuis le contexte de la Portlet :

<GlobalNamingResources>
  ...
  <Resource name="MonPool" auth="Container" type="javax.sql.DataSource"
            username="user" password="password"
            driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://mysql.univ.fr/mabase"
            maxActive="100" maxIdle="30" maxWait="10000" />
  ...
</GlobalNamingResources>
...
<Context path="/uPortal" docBase="/home/uPortal/webapps/uPortal" crossContext="true">
  <ResourceLink name="jdbc/MonPool" global="MonPool" type="javax.sql.DataSource" />
  ...
</Context>
...
<Context path="esup-portlet-test" docBase="/home/uPortal/webapps/esup-portlet-test" crossContext="true">
  <ResourceLink name="jdbc/MonPool" global="MonPool" type="javax.sql.DataSource" />
</Context>

De cette façon, nos deux applications accèdent au même pool.

5. Contenu statique

Comme dans le cas du portail (et de n'importe quelle application Java), il est recommandé de laisser le soin au frontal Apache de délivrer les contenus statiques. Voici un exemple de configuration avec mod_jk permettant de déclarer à la fois les ressources statiques du portail mais également celles de toutes les Portlets respectant la convention du dossier 'images'.

Extrait du fichier de configuration Apache, le contexte du portail étant accessible à la racine d'un VirtualHost :

# On pointe à la racine du webapps où sont placés les contextes uPortal et les Portlets
DocumentRoot "/home/uportal/webapps"
...
<IfModule mod_jk.c>
  # On monte des alias automatiques à la racine de uPortal
  JkAutoAlias /home/uportal/webapps/uPortal
  # On envoie toutes les requêtes à Tomcat
  JkMount /* portal
  # On démonte les accès statiques, les auto-alias feront le reste :
  JkUnMount /media/* portal
  JkUnMount /dtd/* portal
  JkUnMount /static/* portal
  # On démonte les accès statiques aux Portlets le DocumentRoot se chargeant de trouver les fichiers
  JkUnMount /*/images/* portal
</IfModule>

Imaginons une Portlet esup-portlet-test. De façon standard elle a été déployée dans le dossier /home/uportal/webapps/esup-portlet-test. De la même façon, elle est 'montée' dans un contexte du même nom et est accessibles par l'url http://portail.univ.fr/esup-portlet-test. L'accès à une image (ou à n'importe quel contenu statique) se fait au travers d'une URL du genre http://portail.univ.fr/esup-portlet-test/images/icon.gif. Ne trouvant aucun dossier appelé 'esup-portlet-test' à la racine du contexte uPortal pointé par la directive JkAutoAlias, Apache se tourne vers le DocumentRoot et le tour est joué.

A noter que tous les contenus statiques de Portlets se trouvant dans un dossier différent du dossier 'images' seront toujours délivrés par Tomcat, il est donc important d'avoir une règle commune à tous les développeurs (c'est ce qui est préconisé par Spring et déjà utilisé dans les Portlets d'exemple fournies avec uPortal).