Mimic facelet layouts in grails

I wanted to mimic facelets <ui:insert /> and <ui:define /> tags in grails.I find facelets to be quite powerful because it allows to define a fragment in your template that can be redefined by the view, otherwise a default fragment is displayed.It can be useful for instance for a menu where you want all views to use a default menu and some use another menu.

In facelets, you would create a template file and add a <ui:insert /> statement for the menu, like this:

<ui:insert name="menu">
<ui:include src="../frags/menu.xhtml" />
</ui:insert>

Here the <ui:insert/> statement by default includes with the help of the <ui:include/>element a menu fragment (a partial page).

In your view you could if wanted redefine the menu with the <ui:define/> element, like this:
<ui:composition template="layout/template.xhtml">
<ui:define name="menu" />
</ui:composition>

Override default menu here

Grails template system is handled by sitemesh. To achieve the same goal, you can in your template file (layout/main.gsp for instance), add the following element for the menu :

<g:pageproperty name="page.menu" default="${render(template:'/frags/menu')}" />

It achieves the same purpose, actually instead of defining a page section like in facelets, it displays the calling page’s <content> element named menu if present (control is inverted but the result is the same).Otherwise, if the <content> element is not found, the menu fragment is rendered.The fragment page should be in our example created in the frags directory under the name _menu.gsp. In your view, you can therefore define the menu section of your template by declaring a content element.

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="layout" content="main" />
<title>Show Book</title>
</head>
<body>
<content tag="menu">
<div>Override default menu here</div>
</content>
<!-- More content here -->
</body>
</html>

Seam usage in production

There ‘s an interesting thread on the Seam forum about Seam in “profesional use”. Performance and steep learning curve are often mentioned as drawbacks.

Seam heavily relies on proxy based components created by javassist. And javassist is known to be unperformant compared to cglib. This library might have been chosen due to politic reason at JBoss. Seam Managed Persistence Context (SMPC) is also seen as a culprit but i guess that like many other frameworks you have to understand what’s underneath the carpet, lazy loading in some use cases can really hit performance.

Scalability is not mentioned but i guess that since Seam is stateful it also can be an issue for large websites.

For the learning curve, it might be true if you don’t come from the JavaEE world or have never developed JSF applications. Seam still requires good knowledge of JSF 1.X and how it corrects it in many ways. The request lifecycle is also complex albeit powerful.Also other “lightweight” JSF based frameworks are quoted like makefaces.

Seam for me is both a IOC container specialized for web development and a web integration framework of Java EE (Ejb,Web beans), JBoss stack (jBPM, Drools, Richfaces, JSFUnit) and commonly used libraries (quartz,jfreechart, itext, javamail,etc.) It also addresses many commonly asked features (conversations, mail sending, page caching,etc.) I am not sure for the future of Seam. Seam 3 might be a complete rewrite due to support of JSF 2 and JSR-299 aka Java Contexts and Dependency Injection, but it is a comprehensive and efficient web framework with a decent IDE (JBoss tools).

Some Maven tips

First post of the year, here are some Maven tips you might find useful (or obvious for experienced users):

  • How to version commercial libraries in your SCM and use them as dependency ?

In case you don’t have your own central repository and you’d like to version your libraries in your SCM server, you can declare in your pom a repository like this :

<repository>
  <id>sipphonyrepo</id>
  <url>file:///${basedir}/../repository</url>
</repository>

The ‘repository’ directory should be versioned in your scm server but it also means that it should be checked out with your project. Also like any other repository, the dependencies will be copied in your local repository.

*How to just copy files ?

It might be useful on a development machine to copy files while installing an artifact, for instance you might want to copy a JBoss datasource file to a JBoss profile to make sure it’s deployed. For this you can use the Maven resource plugins. For instance the following plugin statement will copy the datasource file to your JBoss server’s default profile deployment directory if JBOSS_HOME environment library is defined (on the development machine) :
<profile>
<id>jboss.deploy</id>
<activation>
<property>
<name>env.JBOSS_HOME</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<artifactid>maven-resources-plugin</artifactid>
<version>2.3</version>
<executions>
<execution>
<id>copy-ds</id>
<goals>
<goal>copy-resources</goal>
</goals>
<phase>install</phase>
<configuration>
<outputdirectory>${env.JBOSS_HOME}/server/default/deploy</outputdirectory>
<resources>
<resource>
<directory>${basedir}</directory>
<includes>
<include>mysql-ds.xml</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
  • How to perform complex build build logic ?

One solution would be to use profiles for that like in the above example. But it can quickly become cumbersome and limited. So a good option is to use Ant Maven plugin with ant-contribs dependency for control statements and loops or even better the groovy GMaven plugin (avoiding XML verbosity).Profiles have still the benefit of clearly identifying an intent in your build. The following command will list all profiles:

mvn help:all-profiles

If build logic can be extracted and used in different contexts, it’s time to create a plugin. It’s quite simple.

  • How to create an artifact of a zip or tar ?

One obvious solution is to use maven assembly plugin but if you need to add some custom logic during packaging, you could just create the zip or tar file with Ant maven plugin or groovy GMaven plugin and gant during the package phase. Then attach the file to your project with Maven build helper plugin and its attach-artifact goal to install it in your repository during the install phase. Once installed in your local repository, the zip or tar file can be become a dependency, just use the proper type in the dependency declaration.

<type>zip</type>
  • How to create a full delivery layout with multiple archetype ?

My advice for creating a comprehensive delivery directory structure would be to use a dedicated module, take advantage of ant,assembly and resource plugins for that. Struts2 has such a module : see the assembly module’s pom

Spring maintenant payant

Oui la nouvelle du week-end ou plutot de fin de semaine sur le changement de licence de Spring me reste en travers de la gorge, même si j’en comprends les raisons.

Mais d’un coup je me sens coupable d’avoir poussé depuis 2004 à l’utilisation de Spring sur plusieurs projets et d’en avoir été le défenseur auprès de certains collègues réticents sur les principes d’injection de dépendances, de conteneur léger et même d’AOP. Sur mes 2 derniers projets, j’ai même introduit Spring Security (anciennement ACEGI) et utilisé Spring MVC pour une petite application interne chez mon employeur précédent. Et oui, le changement de licence s’applique aussi à tous ces projets.Cela me fait maintenant me re-questionner sur l’utilisation de ce framework.

D’abord pourquoi Spring ? Logiquement après avoir lu les livres de Rod Johnson “J2EE design and development” et “J2EE Development without EJB” son utilisation semblait être une vrai alternatives aux Ejb 2.x pour les raisons suivantes :

  • des objets et services métiers n’implémentant aucune interface technique (juste des POJO).
  • l’injection de dépendances favorisant le couplage faible entre les objets.
  • les tests unitaires sans déployer dans le conteneur EJB accélérant ainsi les phases de test.
  • la rapidité de démarrage du conteneur Spring pemettant de l’utiliser en dehors d’un serveur application.
    Mais Spring est aussi utilisé maintenant pour toutes ses fonctionnalités qui facilitent le développement d’application JavaEE :
  • son intercepteurs transactionnels et son annotation @Transactional
  • l’accès aux services des serveurs d’application par simple déclaration (j2ee:jndi-lookup)
  • la création de proxy sur des Ejb (2.1, 3.0), Web-Services (JAX-RPC et JAXWS) .
    En fait, j’ai en fait toujours été très satisfait de Spring Core et impressionné par sa stabilité et son excellente documentation tout cela en opensource et gratuit. Les applications développées avec étaient même plus portables que les traditionnelles applications J2EE. Mais la lune de miel a une fin et je pense maintenant que je vais devoir m’intéresser aux alternatives, car je vois mal certains clients payer pour une librairie (cela changera peut-être pour avec Spring dm Server).

    Les alternatives

Pour moi la + évidente :

  • JavaEE 5 et les EJB 3
    Et oui avec des conteneurs d’EJB en mode embedded pouvant être utilisés pour les tests et démarrant en quelques lignes de codes ( voir par exemple OpenEJB de la fondation Apache ou encore JBoss embedded ). De + cette solution a l’immense mérite d’être standard.Maintenant techniquement, le mécanisme d’interception d’EJB 3 n’est pas aussi riche que celui proposé par Spring et son support d’AspectJ. Le mécanisme ne permet d’injecter uniquement des Ejbs ou des ressources JNDI. Mais au moins les tests sans déploiement sont possibles, le code simplifié et épuré. De +, Ejb 3.1 apportent aussi son lot de nouveautés comme l’annotation @Singleton ou la non-obligation de créer une interface métier.

  • Guice

Peut-être un peu jeune et n’est qu’un “IOC container” mais pourquoi pas pour une utilisation pour des applications standalone.

Some common JSF pitfalls

Well at least here’ s a non exhaustive list of common jsf pitfalls, i felt into (some are variants of others) :

  • Using a converter in a SelectOneMenu or SelectManyList components, be careful of type being applied. See http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&f=82&t=003594. Using an array instead of typed collection for the component input values ( still not sure why, have investigated too much on it, so i won’t extend on it)!
  • Declare a resource bundle in the page ( most of the time bundles are declared in a template page) with the loadbundle element instead of declaring it the faces-config.xml file . If done so, requiredMessage or converterMessage attibutes that can be applied to many UIInput components won’t work (i.e the message won’t be found).
  • With a commandLink inside dataTables with a bean of request scope actions are not executed. At least it happened to me with JSF RI 1.2_07 and is due to the fact that the id of the dataTable component is changed between the component tree creation (restore view phase) and the render response phase ( Update 09/21/2008 : See more explanations on this in the comment section by Dan Allen himself, author of “Seam in Action” ). When submitted on a post back request, the actions event are not queues (passed as hidden fields). It’s well detailled here http://typo.ars-subtilior.com/articles/2007/02/07/jsf-datatable-and-commandlink. As a workaround, i used the tomahawk savestate component for the elements of the datatable. This component stores the state of objects passed as value expression in the component tree (having a scope that spans between the inital request restore view and post back render response phase) . Seam has a page scope for that.
  • Validation errors when using a converter in selectOne* components and not overriding the equals() method for the type of object in the list. More explanation here : http://www.crazysquirrel.com/computing/java/jsf/converter-validation-error.jspx
  • Saving state on client side with hidden fields and having conversion or validation issues with a backing bean of request scope: state is lost. For instance, you have an inputHidden component in your form and for a reason or another a form’s field has conversion or validation issues. The backing bean of request scope is not updated for the postback request. The bean used to display the response is new and the inputHidden‘s field value is reset. Once again this shows a lack of page context for state that needs to be kept between the initial request and the postback request.
  • Programmatic submission of a web form in javascript through form’s submit method won’t work because the actionlistener is registred on a commandButton and when the form is submitted, the submit button parameter is not passed in the request. The button’s action event is not put in the event queue. A workaround is to programmatically click on the form’s command button.

Stat your commits

I recently discover the StatSCM maven plugin and it made our team day . It gives useful information about your Subversion activity (it supports other SCM systems) giving precise developers activity information or file statistics. It also generates some nice charts. I found it very useful to monitor what the team members commit: for instance we discovered that a trainee was the developer of the month (ranked by LOC commited) because he commited some very large csv test files.First to enable it, configure the dependency and declare the report in the reports section of your maven parent pom file:

<pom>
<build>
<plugins>
<plugin>
<groupid>net.sf</groupid>
<artifactid>stat-scm</artifactid>
<dependencies>
<dependency>
<groupid>net.sf</groupid>
<artifactid>stat-svn</artifactid>
<version>0.4.0-StatSCM</version>
</dependency>
<dependency>
<groupid>org.apache.maven.reporting</groupid>
<artifactid>maven-reporting-impl</artifactid>
<version>2.0.4</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupid>net.sf</groupid>
<artifactid>stat-scm</artifactid>
<configuration>
<excludes>
<exclude>**/*.csv</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</reporting>
</pom>

And here some charts produced, like the number of LOC commited by each developer:Number of lines of codeThe day commit activity:Commits activityOr the ration between files addition/modification:

htmlunit kudos

I have been happily surprised by htmlunit. Actually, for a personal project, rewriting a rails app to Seam I tried to find a replacement of excellent Ruby library hpricot. I needed to perform Xpath expression on a HTML DOM tree to retrieve nodes.Well, htmlunit combined with Neko html parser and jaxen Xpath excels at just doing that. Htmlunit is also used by Canoo web testing .Here’s a code snippet to retrieve all USA states on Yahoo Weather :

final WebClient webClient = new WebClient();
final HtmlPage page = (HtmlPage) webClient.getPage("http://weather.yahoo.com/regional/USXX.html");
HtmlUnitXPath xpath = new HtmlUnitXPath("//div[@class='clearfix' and @id='browse']/ul/li/a");
List nodes = (List)xpath.selectNodes(page);
for (HtmlAnchor anchor: nodes) {
System.out.println(anchor.asText());
}

Ok maybe htmlunit could reduce its dependencies and use Xpath support added to Java 5 (via Jaxp 1.3). But that’s what i like about Java plateform: there’s virtually a library for every need. And with (more or less) recent additions to the language: Generics, autoboxing, enums, DSL like code constructions (Fluent Interfaces) and future additions like closures, there are less and less reasons to use dynamically typed languages (even if i like Groovy).

A jBPM review

Here’s a quick review of jBPM and some issues I experimented on a recent project.jBPM features:

  • A bare workflow engine focused on persistence of a business process.
  • Graph oriented programming with different kinds of nodes (wait,action,decision, tasks,etc.) . The graph is represented in XML format following the Jboss Process Definition Language format.
  • Persistence handled by Hibernate.
  • An eclipse plugin to visually design the Business Process and generate the jPDLsource file. It can also generate a web form to enable user interactions with the Business Process (task nodes).
  • BPEL support and integration with Jboss ESB.
  • A web console with JSF components that allows to find process instances, timers, execute tasks and deploy jBPDL processes.
    The main drawbacks with jBPM are:
  • jBPM does not provide any connectors for wait nodes (incoming events) or action nodes (interaction with external systems). You have to code them and use jBPM API for signalling a process instance that it should proceed execution. Also by default, a signal operation on a process instance is synchronous and blocks until it finds a wait node or any node with async attribute set to true .
  • the Business Process can not be published as a web service. You can pass data to the buisness process storing variable in its execution context with the jBPM API.
  • No “business transaction” support.
  • Documentation is not really up-to-date and be prepared to spend time on the wiki and the forums For instance we experienced the following issues:
    • We didn’t use the jBPM console and we spent some time trying to figure out how to start jBPM timers. Well, a JobScheduler had to be started behind the scene .
    • We had troubles with transaction management and integration with JTA transactions. This one was not jBPM’s fault but we spent some time on it. jBPM JobScheduleService delete persisted timers when the business process ends. It does this before the commit of the transaction by registering a JTA’s Synchronization instance on the current JTA Transaction. Our jBPM Hibernate session was also handled by Spring and also registered a Synchronization instance that closed the Hibernate session before commit. Of course, it closed session before the JobScheduler and made the JobScheduler fail to delete timers. As a workaround, we had to use raw Hibernate SessionFactory to prevent this (it avoided Spring ‘s beforeCommit session closing):
      hibernate.transaction.factory_class=org.hibernate.transaction.JTATransactionFactory
      hibernate.transaction.manager_lookup_class=org.hibernate.transaction.JBossTransactionManagerLookup
      hibernate.current_session_context_class=org.hibernate.context.JTASessionContext

      and setting the following property of the LocalSessionFactoryBean:
      <property value="false" name="exposeTransactionAwareSessionFactory"></property>

      Also, we used the Spring jBPM module since our jBPM actions, decision handlers were implemented as Spring beans. Spring module offers workflow deployments features but we found little value in Spring modules since it’s quite easy to extend jBPM to look for Spring beans in a Spring context. The jBPM Spring module does not seem to be maintained anymore.So, jBPM is really a bare workflow engine and we hope it will offer tigher integration with Jboss ESB for connection with external systems and also more advanced features.Seam offers integration with jBPM : you can register a jBPM process definition as a Seam component, and let Seam deploy it. Seam also provides some anotations to interact with a business process to share data (bijection) with it or start it in a Seam conversation. Seam’s adoption will probably boost jBPM’s usage, well at least i am looking forward to it.