Développement
Problème Jetty / Maven sous Windows
par David Pilato le fév.24, 2010, sous la catégorie Maven
Lorsqu’on souhaite lancer une WebApp avec le plugin Jetty sous Maven 2 depuis un PC sous windows on obtient une erreur référencée sous JIRA #JETTY-1063 :
java.net.URISyntaxException: Illegal character in path at index 18: file:/C:/Documents and Settings/USER/.m2/repository/org/mortbay/jetty/jetty-maven-plugin/7.0.0.1beta2/jetty-maven-plugin-7.0.0.1beta2.jar
Ce problème n’est résolu que sous Maven 3. Pour ceux qui souhaitent rester sous Maven 2 (Maven 3 est encore en version alpha), il faut modifier l’emplacement de la repository pour éviter le souci du caractère ESPACE présent dans le chemin C:\Documents and settings\USER\.m2\repository (chemin par défaut).
Il est fortement recommandé de déplacer le répertoire repository dans c:\maven2\repository par exemple et modifier ensuite le fichier settings.xml qui se trouve normalement dans C:\Documents and settings\USER\.m2 ou (moins bien) dans votre répertoire d’installation de maven sous /conf.
<localRepository>/c:/maven2/repository</localRepository>
Ainsi, Maven ira chercher les libs dans un répertoire sans espaces…
Utilisation du mode Lazy d’Hibernate avec Struts et Spring
par David Pilato le fév.24, 2010, sous la catégorie Java
Lorsqu’on utilise Hibernate pour déléguer la gestion de la persistence, se pose alors le classique problème de l’exception LazyInitialisationException.
En effet, dans une modélisation assez classique, imaginons le cas suivant :
Couche Modèle (ou DAO)
Classe POJO contenant un attribut x et une collection cols
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
public class Dossier {
@Id
@GeneratedValue
private Long id;
private String x;
@OneToMany(cascade=CascadeType.ALL)
private Collections<String> cols;
// Getter et setters
}
Classe DAO
Voir le blog pour l’utilisation des generics de Java5 afin d’éviter d’avoir à coder toujours les mêmes méthodes CRUD.
@Repository
@Transactional
public class DossierDAO {
@Autowired
protected SessionFactory factory;
public Dossier getOne (Long id) {
Session session = factory.getCurrentSession();
return (Dossier)(session.get(Dossier.class,id));
}
}
Couche Métier (ou Service)
Classe Service contenant l’injection du DAO
@Transactional
public class DossierServiceImpl implements DossierService {
@Autowired
@Qualifier("dossierDao")
private DossierDAO dossierDao;
public Dossier read(Long id) {
return dossierDao.getOne(Dossier.class.getName(), id);
}
}
On voit ici que la transaction peut démarrer au niveau du service et que par défaut, en mode Lazy, seul l’attribut x de Dossier sera chargé.
Pour que l’application Web appelante puisse faire une itération sur la collection, il faudrait que celle-ci soit chargée.
Il est possible de changer le mode LAZY pour dire à Hibernate de tout récupérer mais pour un arbre de données assez profond, cela peut devenir désastreux.
Il est également de modifier la méthode read du service DossierService ainsi :
public Dossier read(Long id) {
Dossier d = dossierDao.getOne(Dossier.class.getName(), id);
d.getCols();
return d;
}
Dans ce cas, on a déclenché manuellement la recherche du contenu de la collection…
Autre possibilité, garder la connexion avec Hibernate pendant tout le temps du traitement de la requête Web de l’utilisateur.
Pour se faire, on doit ouvrir la transaction au début du traitement de la requête pour ne la restituer qu’à la fin de la génération de la vue.
On modifie le web.xml :
<filter> <filter-name>OpenSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> </filter> <filter-mapping> <filter-name>OpenSessionInViewFilter</filter-name> <url-pattern>*.do</url-pattern> </filter-mapping>
Dans cette configuration, le filtre OpenSessionInViewFilter mis sur tous les appels *.do va déclencher une ouverture de session hibernate jusqu’à la restitution de la vue.
Ainsi, si dans la JSP, on trouve une itération de l’attribut cols du bean Dossier, un appel à la base de données via Hibernate sera déclenché à ce moment là (et seulement à ce moment là).
Autrement dit, si pour une autre JSP vous n’avez pas besoin d’afficher la collection, l’appel à la base ne sera pas réalisé.
Publication de documentation fonctionnelle avec Maven
par David Pilato le fév.23, 2010, sous la catégorie Maven
Lorsqu’on utilise Maven, se pose souvent la question de génération de documents à intégrer dans le site web généré par Maven.
Au début, j’ai regardé le format APT qui a l’avantage certain de générer du contenu directement consultable sous forme de page Web. Il existe de plus un plugin qui permet de fabriquer un PDF en regroupant les fichiers APT souhaités.
Mais, cela reste un nouveau langage à apprendre pour des équipes fonctionnelles et le format APT est trop limité pour permettre un travail efficace par les équipes de conception ou d’analyse.
Après avoir tourné et viré, testé quelques solutions, j’en suis arrivé à la conclusion que le plus pratique est de laisser les concepteurs utiliser leurs outils office (Microsoft ou oOo) et de transformer ces documents en PDF lors de la fabrication du site.
Pour cela, un petit plugin miracle (jodconverter-maven-plugin) couplé à oOo permet de faire le travail.
Tout d’abord, il faut lancer oOo en mode serveur. Sous Linux, ça se fait comme ça :
/opt/openoffice.org3/program/soffice -headless -accept="socket,host=localhost,port=8100;urp;" -nofirststartwizard
Sous Windows :
"C:\Program Files\OpenOffice.org 3\program\soffice.exe" -accept="socket,host=localhost,port=8100;urp;"
Puis ajouter dans le pom.xml :
<build>
<plugins>
<plugin>
<groupId>com.artofsolving</groupId>
<artifactId>jodconverter-maven-plugin</artifactId>
<version>2.2.3</version>
<inherited>false</inherited>
<configuration>
<sourceDirectory>${basedir}/src/site/docs</sourceDirectory>
<outputDirectory>${project.reporting.outputDirectory}/docs</outputDirectory>
<include>**/*.odt,**/*.odp</include>
<outputFormat>pdf</outputFormat>
<port>8100</port>
</configuration>
<executions>
<execution>
<id>convert</id>
<phase>pre-site</phase>
<goals>
<goal>convert</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Ainsi, lors de la génération du site, tous les documents odt ou odp présents dans le répertoire /src/site/docs et sous-répertoires seront transformés en documents PDF dans le répertoire de sortie du site sous /docs. Les sous-répertoires sont également recréés.
Il ne reste plus qu’à faire des liens vers ces documents générés que ce soit dans site.xml ou dans un fichier APT.
Dans l’exemple suivant, le fichier source MonDoc.odt se trouve dans /src/site/docs/1.
<!-- Extrait du site.xml --> <body> <menu name="Fonctionnel"> <item name="Mon document" href="./docs/1/MonDoc.pdf" /> </menu> </body>
Dans le cadre des projets que je gère, j’ai mis en place Hudson qui me reconstruit toutes les nuits une vision documentaire de mes projets. Ainsi, lorsqu’un concepteur valide dans CVS ou SVN pendant la journée un document, il est automatiquement publié la nuit sur le site Maven correspondant.
Autre intérêt : à chaque livraison (release), une photographie complète de l’état de la documentation au moment de la fabrication des livrables est générée. Il est ainsi possible de retrouver facilement le contexte fonctionnel d’une version particulière…
La mise en place d’une Forge
par David Pilato le jan.26, 2010, sous la catégorie Développement
Pour les besoins internes de la douane, j’ai proposé la mise en place d’une forge afin de consolider nos moyens de développement et de gestion de projets.
Histoire d’être cohérent avec d’autres choix faits par l’administration, projet Adullact, j’ai retenu la forge GFORGE.
Je vais décrire ici le processus d’installation que je vais suivre afin de partager cette information avec d’autres personnes qui pourraient être intéressés par cette démarche.
Installation de la Forge sur Ubuntu 9.10
Tout d’abord, il faut télécharger les sources de la forge. Je me suis basé sur la dernière version connue à ce moment : 5.7b2 Community Edition.
Correction du problème avec Postgresql
La version de postgres téléchargée par Ubuntu ne correspond pas à la version attendue dans le script d’installation install-gforge-2-db.php.
Pour corriger ce problème, j’ai remplacé partout (sauf à la fin) la version 8.3 par 8.4.
Par exemple la ligne
'/etc/init.d/postgresql-8.3',
est devenue
'/etc/init.d/postgresql-8.4',
Correction du problème avec la distribution Apache pour Ubuntu (Rewrite)
La gestion de la configuration Apache n’est pas « standard » sur Ubuntu. J’ai donc suivi les recommandations du blog de Josh Street pour corriger le problème.
cd /etc/apache2/mods-enabled sudo ln -s ../mods-available/rewrite.load rewrite.load sudo service apache2 start
Finalement, Adullact a annoncé vouloir passer sous FusionForge qui est un fork de GForge afin de conserver la forge dans le monde open-source. La team FusionForge travaille en ce moment sur la version 5.0 mais elle n’est pas encore stabilisée. Nous allons donc installer la version 4.8.3.
La mise en place de FusionForge est abordée dans cet article.
David
Découverte de Google App Engine pour Java
par David Pilato le jan.23, 2010, sous la catégorie Développement, Java
En lisant le magazine de développez.com (Décembre 2009 – Janvier 2010), j’ai découvert l’ouverture du service Google App Engine au monde Java.
De quoi s’agit-il ?
Ni plus, ni moins que ce que tout développeur Java cherche : un hébergement gratuit d’applications Java. Bon, il ne s’agit pas d’un serveur J2EE du type JBoss, Glassfish ou autre mais il permet de faire tourner des applications Web (des Webapps Java) et de pouvoir y intégrer les outils Google.
Je viens juste de créer mon compte, de diriger mon domaine vers ce site et de faire tourner une application de base générée avec le plugin Eclipse pour google.
Je vais compléter cet article au fur et à mesure de découvertes…
Stay tuned !