Retour sur GWT
Après quelques semaines sur GWT, je me suis vite lassé. Si on n'a pas d'éediteur graphique digne de ce nom ou une librairie intéressante de widget,on perd pas mal de temps à réaliser des applications dignes de ce nom ( à moins de s'appeler google biensûr...) Je suis donc revenu aux fondamentaux et me voila revenu sur JSF. J'en ai profité pour tester la version 2.0 sur Google App Engine. Et la c'est le drâme. C'est un vrai parcours du combattant ou un champ de mines, à vous de voir.
Problèmes rencontrés
Pas mal de problèmes que j'ai eu ont été résolus en me référant sur ce tutoriel ou sur cette page chez google
Pour faire simple, voici un résumé des problèmes
- La version 1.3.2 de l'appengine ne fonctionnait pas chez moi avec netbeans
Obligé de passer en 1.3.1 - L'implémentation standard de JSF2 n'est pas supporté par défaut dans GAE car elle utilise la classe InitialContext qui n'est pas supportée.
- Il y a pas mal de paramètres à ajouter dans le web.xml ( cf ci-après )
- Pas de page de debug de facelets car nous sommes obligé de travailler dans un mode différent de DEVELOPMENT
- Le scope VIEW n'est pas "trop" supporté
- Problème XALAN ( voir après)
Dépendances à ajouter
Commons-logging
Petite dépendance nécessaire et qui n'apparaît qu'à l'éxecution
log4j
Idem
facestrace
Très utile pour le debug. De plus ce composant est bien intégré à primefaces. Il suffit d'ajouter le paramètre de requête HTTP trace=true pour que la console facestrace apparaisse.
xalan
Si comme moi vous avez l'erreur suivante
com.sun.faces.config.ConfigurationException: CONFIGURATION FAILED!
com.sun.org.apache.xalan.internal.xsltc.runtime.BasisLibrary is a restricted class. Please see the Google App
Engine developer's guide for more details.
Vous devez ajouter les librairies serializer.jar et xalan.jar provenant du projet xalan dans le répertoire WEB-INF/lib de votre webapp.
Ma Configuration
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <display-name> wine cellar </display-name> <description> wine cellar </description> <!-- ***** GAE 1.3.0 appears to handle server-side state saving. ***** --> <context-param> <param-name>javax.faces.STATE_SAVING_METHOD</param-name> <param-value>client</param-value> </context-param> <context-param> <param-name>javax.faces.PROJECT_STAGE</param-name> <param-value>Production</param-value> </context-param> <context-param> <param-name>javax.faces.DEFAULT_SUFFIX</param-name> <param-value>.xhtml</param-value> </context-param> <context-param> <param-name>com.sun.faces.expressionFactory</param-name> <param-value>com.sun.el.ExpressionFactoryImpl</param-value> </context-param> <context-param> <description> Set this flag to true if you want the JavaServer Faces Reference Implementation to validate the XML in your faces-config.xml resources against the DTD. Default value is false. </description> <param-name>com.sun.faces.validateXml</param-name> <param-value>true</param-value> </context-param> <!-- ***** Accommodate Single-Threaded Requirement of Google AppEngine --> <context-param> <description> When enabled, the runtime initialization and default ResourceHandler implementation will use threads to perform their functions. Set this value to false if threads aren't desired (as in the case of running within the Google Application Engine). Note that when this option is disabled, the ResourceHandler will not pick up new versions of resources when ProjectStage is development. </description> <param-name>com.sun.faces.enableThreading</param-name> <param-value>false</param-value> </context-param> <!-- primefaces --> <context-param> <param-name>com.sun.faces.allowTextChildren</param-name> <param-value>true</param-value> </context-param> <!-- Faces Servlet --> <context-param> <param-name>com.sun.faces.enableMultiThreadedStartup</param-name> <param-value>false</param-value> </context-param> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet> <servlet-name>Resource Servlet</servlet-name> <servlet-class> org.primefaces.resource.ResourceServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>Resource Servlet</servlet-name> <url-pattern>/primefaces_resource/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern> <url-pattern>*.jsf</url-pattern> </servlet-mapping> <session-config> <session-timeout>30</session-timeout> </session-config> <welcome-file-list> <welcome-file>index.jsp</welcome-file> <welcome-file>index.xhtml</welcome-file> <welcome-file>index.html</welcome-file> </welcome-file-list> </web-app>
Le fichier faces-config.xml
<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"> <application> <locale-config> <default-locale>en</default-locale> </locale-config> </application> <managed-bean> ... </managed-bean> </faces-config>
Limitations
Et oui il y a des limitations à tout ça : L'un des gros plus de la spec JSF2 est la scope view qui permet de conserver l'état d'un composant au sein d'une page dans n'importe quelle étape du cycle de vie JSF. Bref, c'est entre le scope session et le scope request. GAE ne semble pas trop le supporter. Il est même préférable de n'utiliser que le scope request. Personnellement j'ai du adapter mon design à un mode réellement sans état. GAE ne supporte pas le PROJECT_STAGE Development Il faut donc le paramétrer tel quel
<context-param> <param-name>javax.faces.PROJECT_STAGE</param-name> <param-value>Production</param-value> </context-param>
Cette configuration semble occulter la page d'erreur standard de facelets qui est très utile pendant le développement. Heureusement facestrace est la.
Enfin, l'une des grosses limitations est la suppression des données entre chaque arrêt/relance du SDK GAE. Je n'ai pas encore cherché trouvé comment les garder en mémoire.
Conclusion
A cette armé mexicaine de composants, il ne me manque qu'une solution d'IoC ( probablement CDI ) et surement un framework d' AOP. GAE fournit déjà pas mal de composants permettant de gérer les objets en mémoire et d'améliorer les perfs.
La suite dans un prochain numéro...




6 réactions
1 De Pluviotor - 25/04/2010, 13:38
Je suis très très decu de Jsf.
Je pense que Wicket est mieux.
2 De cestpasdur - 04/05/2010, 13:29
Quelle critique constructive Pluviotor. Essaye un peu JSF et reviens avec de vrais arguments stp.
3 De pluviotor - 06/05/2010, 14:38
Bah j'ai déjà essayé Jsf sur un projet.
J'ai tester Rich faces, tomahawk, Icefaces, rich component. Ils respectent tous l'api Jsf.
Par contre, une page jsf selon ces implémentations n'a pas la même tronche.
Et les actions (Java) en sont très dépendantes (de ces implémentations).
C'est ca qui me plait pas. (certains ont fait une retour arrière à struts et ca me choque pas). Tu change une impl de Jsf, t'as toute la couche de présentation à bazarder.
Les composants à tuner, te font attraper la calvitie.
Wicket à l'air plus simple, c'est le code java qui instancie les composants et la page (la vue ) qui en dispose. Possibilité de composant complexe, hierarchie...
Ca me plait, c'est comme le swing.
C'est ce que je recherchais depuis longtemps.
Côté perf/rapidité de dev ca a l'air de vraiment tenir la route(/gwt,Jsf..).
https://cwiki.apache.org/WICKET/#In...
Mais, j'avoue ne pas avoir encore pratiqué Wicket.
4 De cestpasdur - 06/05/2010, 21:49
Il y a les implémentation JSF : Sun RI et Myfaces, qui sont accompagnées de librairies de composants graphiques telles que Richfaces et IceFace.
Si tu changes de librairies de composants, il est vrai que tu devras recoder une bonne partie de tes vues, mais en pratique cela n'arrive pas souvent, tu en choisis une et tu t'y tiens. Si besoin, tu peux facilement créer ta propre librairie (encore plus vrai depuis JSF2)
Wicket n'a pas de librairies graphiques aussi élaborées que JSF.
GWT, lui a plusieurs librairies de composants graphiques : SMartGWT, GXT... Mais tu devras changer tout ton code client si tu changes de librairies également.
Après, j'avoue que JSF est assez compliqué, et on en apprends tous les jours. Mais celui ci se bonifie tous les jours et c'est à mes yeux le meilleurs framework web d'entreprise.
5 De Pluviotor - 07/05/2010, 22:31
Ton blog est très interessant (je l'ai découvert par le planet).
Et comme c'est un peu rare d'avoir des codeurs j2ee sous ubuntu, j'aime bien partager les points de vue ( sans chercher à imposer le mien).
Perso, voilà un composant dont je n'ai pas reussi à réaliser sous Jsf:
http://www.wicket-library.com/wicke...
J'ai pourtant ouvert les sources de plusieurs implémentations Jsf, pour les modifier (Tomahawk c'est étonnamment crado au niveau du code ).
Avec Rich faces (avec des datatable datagrid), on peut mais c'est de la bidouille non réutilisable et crade pour à peine arriver au même résultat.
Certes cet exemple wicket n'est pas bluffant, mais le modèle derrière est très propre et simple. Ce type de composant avec noeud et cellulle éditable permet de faire de l'economie de dev Ihm.
Le côté complexe (Jsf) ne me rebute pas, si je ne sais pas qu' il y a plus simple ailleurs
Je te conseille de voir ce site: http://www.yeswicket.com/.

Après j'arrête de faire de la pub pour une techno non pratiqué.
6 De duyhai - 04/03/2011, 02:31
Pour les structure d'arborescence (tree) il y a PrimeFaces qui en propose un de très bien. RichFaces 3 en propose aussi..
http://goo.gl/xa4Z6