Grails Plugin for SmartGWT
We are pleased to announce a preview version of our plugin for Grails developers.
Grails includes an ORM layer (GORM) built on top of Hibernate and the principal feature of this plugin is to provide a seamless integration with it. The plugin also assists with creating UI elements and providing SmartClient-enhanced scaffolding.
This articles serves as a starting point for developers looking to begin using this integration. It assumes familiarity with Grails, SmartClient & the Grails GWT integration. This release is a preview so it hasn’t undergone the normal QA process that our normal releases include, at this point we’re looking for developer feedback.
Plugin features
- Automated SmartClient deployment
- SmartClient DataSource generation from Grails Domain Classes
- Groovy DSL to generate/manipulate custom Component Schema
- Automatic mapping of Grails domain class validators to SmartClient validators
- Full CRUD support including AdvancedCriteria queries, paging and sorting (through an included Custom Server DataSource)
- Grails Tag Libraries to assist with the loading of DataSource and UI components
- SmartGWT based scaffold generation.
Pre-requisites (for sample application)
- A working Grails installation (1.3.6 or above)
- Grails SmartGWT plugin (current beta version is 0.4 available here)
- SmartGWT-Enterprise downloaded and extracted (evaluation builds available here)
- MySQL (required for this sample only, any GORM-supported database will work with the SmartGWT plugin)
Getting Started
We’re going to use Grails on Sakila for the basis of a sample app. The MySQL Sakila sample database (included) contains a lot of seed-data that will allow us to explore the features of this plugin. I’ve updated the app to use Grails 1.3.6, removed the authentication filter and replaced the index.gsp to show a list of Controllers.
The sample app, database schema and sample data can be downloaded here. The following steps are required to get the app running:
- Create the database schema (from sakila-schema.sql)
- Load the seed data (sakila-data.sql)
- Open grails-app/conf/DataSource.groovy and update the database url, username and password to suit your environment
Run the application (‘grails run-app’ from the ‘grails-on-sakila’ directory) and browse to the URL (by default http://localhost:8080/grails-on-sakila/), you should see:

You can click on some of the implemented controller views (e.g. Actor) and you should get:

At this point we have a standard Grails application with some sample data.
Installing the SmartGWT plugin
We’re now going to add the Grails GWT plugin and the SmartGWT plugin:
- grails install-plugin gwt
- grails install-plugin <PATH_TO_SMARTGWT_PLUGIN>/grails-smartgwt-server-0.4.zip
- You will be prompted to provide the path to SmartGWT-Enterprise directory (download and extract an evaluation build from here)
Beginning with SmartGWT and SmartGWT Scaffolding
Open the Actor, Category, Film and Language domain class files and add ‘static smartclient’ inside the class definition. The plugin will now automatically implement the IToJSON interface to allow the SmartClient server to serialize domain class instances.
Now we’re ready to generate the SmartClient DataSource definitions and scaffolding:
- grails generate-data-source
- This script will generate SmartClient DataSources for all the domain classes that we’ve exposed so far to SmartClient
- The generated DataSource files can be found in grails-on-sakila/smartclient/ds.
- grails generate-scaffolding scaffold.gsp com.example.smartgwt.Scaffolding
- This script will generate a GWT Host Page (named scaffold.gsp), a GWT Module (com.example.smartgwt.Scaffolding) and SmartClient Component Schema for List Grids, Dynamic Forms and Detail Viewers.
- The generated UI files can be found in grails-on-sakila/smartclient/ui
Finally we need to compile the GWT module and run the app:
- grails compile-gwt-module
- grails run-app
- Browse to the scaffold gsp file (e.g. http://localhost:8080/grails-on-sakila/scaffold.gsp)
You should be presented with a list of Domain classes that can be clicked and will appear in a ListGrid in the middle view:
The scaffolding feature supports testing queries using the Filter Builder, paging, sorting, and editing records.
Next steps
In a future post we’ll look at how to customise the scaffolding to better handle associations, provide formatting, as well as how to create stand-alone (non-scaffolded) SmartGWT pages and modules.
Grails plugin for SmartGWT & SmartClient | Thoughts, Ideas and Perspectives on Technology
[...] UIs simpler. So if you will be so kind, please hop over to the SmartClient blog and take a look: Grails Plugin for SmartGWT.Incidentally, I’ve had some great support from the guys at Isomorphic (makers of SmartClient) [...]
GroovyMag - the magazine for Groovy and Grails developers about Groovy programming and Grails development
[...] folks at Isomorphic Software have posted about a preview version of their SmartGWT plugin for Grails. This includes a nice tutorial (with screenshots!) for getting started with the [...]
haytone
It’s a great plugin and post!
Can I use this plugin with smartGWT LGPL Edition?
d.cavestro
That’s great news, I’ll give it a try soon
Till now I’ve been happy with SmartGWT (LGPL) and grails applications: the best results came using at server side REST services through the simple yet wonderful jax-rs plugin http://code.google.com/p/grails-jaxrs/.
If you are interested I can give you more details.
Cheers
Davide
An Army of Solipsists » Blog Archive » This Week in Grails (2011-28)
[...] Grails Plugin for SmartGWT [...]
norith
The Grails plugin is really interesting and could solve some major integration issues for me. One question though: is the Enterprise license actually required? Could the Power or Pro level license be used instead?
Since the Power level alone is $1900, the Enterprise level is likely beyond my reach.
ckendrick
Hi Norith,
The Grails plugin depends only on the features of our Pro product ($745 per developer). Currently, we have only the one evaluation package and it contains all available features so it’s labelled the Enterprise Evaluation, but in this usage, you could follow the same steps with a licensed Pro package.
fatzopilot
Hi,
Congrats for this plugin and the new smartGWT 3.0 release! I am even more happy to see that it will work with the Pro version.
Just tried the plugin with Grails 2.0.0 RC3 and the Sakila sample and ran into several problems, like this one:
| Error 2011-12-07 14:04:25,092 [main] ERROR digester.Digester – Begin event threw exception
Message: taglib definition not consistent with specification version
Line | Method
->> 501 | startElement in com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser
- – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - –
| 1363 | scanStartElement in com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl
| 2756 | next . . . . . . in com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver
| 648 | next in com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl
| 511 | scanDocument . . in com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl
| 808 | parse in com.sun.org.apache.xerces.internal.parsers.XML11Configuration
| 737 | parse . . . . . in ”
| 119 | parse in com.sun.org.apache.xerces.internal.parsers.XMLParser
| 1205 | parse . . . . . in com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser
| 522 | parse in com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser
| 114 | doStart . . . . in org.grails.plugins.tomcat.InlineExplodedTomcatServer
| 102 | start in org.grails.plugins.tomcat.TomcatServer
| 175 | doCall . . . . . in _GrailsRun_groovy$_run_closure5_closure12
| 152 | doCall in _GrailsRun_groovy$_run_closure5
| 120 | runInline . . . in _GrailsRun_groovy
| 66 | doCall in _GrailsRun_groovy$_run_closure1
^ 33 | doCall . . . . . in RunApp$_run_closure1
| Error 2011-12-07 14:04:25,244 [main] ERROR startup.ContextConfig – Parse error in application web.xml file at file:/C:/Users/fatzopilot/.grails/2.0.0.RC3/projects/grails-on-sakila/resources/web.xml
Message: Error at (275, 11) : taglib definition not consistent with specification version
Line | Method
->> 501 | startElement in com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser
- – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - –
| 1363 | scanStartElement in com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl
| 2756 | next . . . . . . in com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver
| 648 | next in com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl
| 511 | scanDocument . . in com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl
| 808 | parse in com.sun.org.apache.xerces.internal.parsers.XML11Configuration
| 737 | parse . . . . . in ”
| 119 | parse in com.sun.org.apache.xerces.internal.parsers.XMLParser
| 1205 | parse . . . . . in com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser
| 522 | parse in com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser
| 114 | doStart . . . . in org.grails.plugins.tomcat.InlineExplodedTomcatServer
| 102 | start in org.grails.plugins.tomcat.TomcatServer
| 175 | doCall . . . . . in _GrailsRun_groovy$_run_closure5_closure12
| 152 | doCall in _GrailsRun_groovy$_run_closure5
| 120 | runInline . . . in _GrailsRun_groovy
| 66 | doCall in _GrailsRun_groovy$_run_closure1
^ 33 | doCall . . . . . in RunApp$_run_closure1
Caused by IllegalArgumentException: taglib definition not consistent with specification version
->> 501 | startElement in com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser
- – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - –
| 1363 | scanStartElement in com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl
| 2756 | next . . . . . . in com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver
| 648 | next in com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl
| 511 | scanDocument . . in com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl
| 808 | parse in com.sun.org.apache.xerces.internal.parsers.XML11Configuration
| 737 | parse . . . . . in ”
| 119 | parse in com.sun.org.apache.xerces.internal.parsers.XMLParser
| 1205 | parse . . . . . in com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser
| 522 | parse in com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser
| 114 | doStart . . . . in org.grails.plugins.tomcat.InlineExplodedTomcatServer
| 102 | start in org.grails.plugins.tomcat.TomcatServer
| 175 | doCall . . . . . in _GrailsRun_groovy$_run_closure5_closure12
| 152 | doCall in _GrailsRun_groovy$_run_closure5
| 120 | runInline . . . in _GrailsRun_groovy
| 66 | doCall in _GrailsRun_groovy$_run_closure1
^ 33 | doCall . . . . . in RunApp$_run_closure1
| Error 2011-12-07 14:04:25,278 [main] ERROR startup.ContextConfig – Occurred at line 275 column 11
| Error 2011-12-07 14:04:25,357 [main] ERROR startup.ContextConfig – Marking this application unavailable due to previous error(s)
| Error 2011-12-07 14:04:25,749 [main] ERROR core.StandardContext – Error getConfigured
| Error 2011-12-07 14:04:25,759 [main] ERROR core.StandardContext – Context [/grails-on-sakila] startup failed due to previous errors
Any chance this will be fixed soon?
Thanks
ckendrick
Hi Fatzopilot, if that’s still happening for you when Grails 2.0 is released, be sure to let us know. However, probably want to post this to the forums instead, and if possible, figure out what XML file is causing Grails to report this error.
vmihaylov
What about grails-2.0 ? I tried using the plugin with that version and things went bad? Can you confirm whether grails-2.0 is supported, and/or when you will update the plugin?
ckendrick
Hi Vmihaylov, it looks like Grails 2.0 has made some non-backwards-compatible changes in databinding. The plugin code needs to be adjusted to compensate. We’ll let you know when a new version is available.
fatzopilot
Hi, I am currently playing around with the Sakila sample and Grails 1.3.7 and found some issues. Does it make sense to file them somewhere and if, where?