Plugins You can find out about all the publicly available Grails plugins.

ICEfaces - JSF Integration

  • Tags: /
  • Latest: 0.3
  • Last Updated: 02 June 2010
  • Grails version: 1.2.0 > *
  • Authors: null
2 votes
compile "org.grails.plugins:icefaces:0.3"




Type :
install-plugin icefaces

When icefaces-plugin is starting, a copy of the generated web.xml is done into /web-app/web-inf/web.xml. This is due to a tomcat plugin bug when fetching webXmlLocation property. Do a backup of your file or include it in your src/template/web.xml.



The plugin try to simplify JSF ICEfaces ( ) development and smooth JSF to Grails migration. It could be adapted for other frameworks but ICEfaces brings easy AJAX/AJAX push for today applications. JSF is like Spring before Grails, lot of xml. The plugin solves this by using multiple conventions for managed beans, el context, message bundle and detected navigation-case. You could also start project with this plugin by using static scaffolding provided. From some domain classes you can generate collaborative CRUD.

  • The base of this work is a work in progress migration of iceScrum ( ), an agile project management open source tool.
  • You can see it as an alternative to integrated JSF frameworks such as JBOSS Seam.
  • If you want to leverage groovy&grails power with grails plugins like spring web flow even using controllers/services to serve fragments or webservices, this one if your solution.
There is also a JSF 2 port available.

JSF-Icefaces-Facelet integration

  • Bean By convention (no need for faces-config)
  • Bean access to controller parameters (session,request,params...)
  • Navigation Case by convention (extension auto added, local path searched, .redirect extension)
  • Beans dynamic methods for navigation redirect(action?,bean?,view?,uri?,url?) and render(action?,view?,bean?),
  • Automatic bean and service properties resolution
  • 'void init()' called at bean initialization if present
  • 'void dispose()' called at bean destruction if present
  • ICEfaces Extended request scope ('page')
  • 'RealTime changes' in dev mode : updates of your Beans and Views are pushed to browsers while running
  • Access to web.xml-config configuration via IcefacesConfig.groovy
  • Access to faces-config generated in web-app/faces-config.xml
  • Converters for locale, currency, timezone
  • i18n ready, fast access with #{msg['key']}
  • create-bean script
  • generate-bean, generate-views-icefaces, generate-all-icefaces : scaffolding for JSF collaborative application
  • "Contextual push", allowing method invokation from target user contexts (manage session-page objects in minutes)
  • Hibernate session managed from view rendering to view response
  • Execute groovy code in EL expression ( #{ice.groov[' def i = 2; 3.times{ i++ }; i; ']} )
  • easy access to ExpressionLanguage in beans : el "#{valueExpression}"

Extra methods for beans :

  • push(String group?) - render target group (default:all),
  • pushJavascript(String group?, String js) - call javascript on target group users (default:all),
  • pushInvoke(String group?, Closure meth) - call closure from target group user contexts (default:all),
  • pushInvokeInBean(String group?, Closure meth) - call closure from target group user bean contexts (default:all),
  • javascript(String js) - call javascript on the actual request,
  • redirect(action?,bean?,view?,uri?,url?),
  • render(action?,view?,bean?)
  • msg(code,default?,args?,locale?) - Bundle bindning
  • joinChannel(String group) - join push channel
  • leftChannel(String group) - left push channel
*UPDATED on release 0.1 (+) el "#{valueExpression}" : resolve EL expression

_ This is an Early Release, be cool if bugging ;) Main objective was JSF Icefaces integration. JSF 2 impl coming.

Sample code

Use of create-bean package.Class will do this :

package app

class DummyBean{

def static scope = 'page'

//['page' (icefaces special request scope),'request','session','globalSession' (portlet),'conversation'(swf),'flow'(swf)]

def property = "hi" def oldProperty = "bye"

//def otherBean (autowired bean)

void init(){ //called when bean starts }

void dispose(){ //called when bean stop }

/*String action() { }*/

void say(javax.faces.event.ActionEvent ae) { pushJavascript "alert('${property}!');" // render "test2.iface" change view // redirect "test.iface" redirect view, forcing page scoped bean clean }

void change(javax.faces.event.ActionEvent ae) { pushInvokeInBean { def changed = property property = oldProperty oldProperty = changed } } }

  • "pushJavascript" is a new method you can use to broadcast javascript.
  • "pushInvokeInBean" will replicate as many dummyBean registered (so as many page opened with option icefaces concurrent view at true). Note that closure resolve strategy is delegate first and the delegate is set on the specific target bean.
Here the text.jspx page (called via configured extension, by default text.iface)

<?xml version='1.0' encoding='utf-8'?>
<f:view xmlns:ice="" xmlns:f="">
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>        
        <ice:outputText value="#{}"/>
        <ice:commandButton value="say #{}" actionListener="#{dummyBean.say}"/>
        <ice:commandButton value="prepare  #{dummyBean.oldProperty}" actionListener="#{dummyBean.change}"/>

Navigation by convention

Here some equivalents methods

<ice:commandLink action="/bean/test.iface" />
<ice:commandLink action="/bean/test" />
<ice:commandLink action="test" />
<ice:commandLink action="test.iface" />

From bean you can use

render action:"/bean/test.iface" //and the equivalents seen before
render "/bean/test.iface" // == render action:*
render view:"test" // == /bean/test.iface
render bean:"bean2" // /bean2/index.iface
render bean:"bean2",view:"test" :// /bean2/test.iface

Sample redirect convention

redirect url:""
redirect action:"test"
render action:"test.redirect"
<ice:commandLink action="test.redirect" />