Grails/Groovy for the frontend
When I started building my service, I knew I would have to choose a technology for the frontend. One of the big challenge is that there is a big number of available frameworks and languages to choose from: servlets + jsps, spring mvc, PHP, ruby on rails, grails, and many more including as a last resort to build my own. Each solution has their advantages and drawbacks. I think one of the big issue I am seeing in the choice is that it is hard (or at least costly) to switch from one to another once the choice has been made. Even if they are close to each other in concepts they each have their own ways of doing things (including the language, like PHP vs Grails/Groovy...). Also, depending on the technology, you get more or less: for example, Grails is much more than a UI framework with its powerful ORM layer (Object Relational Mapping).
In the end, making the decision was not too difficult as I was able to come up with some boundaries and constraints:
- Ability to talk to java back-end services (with extra bonus if I could collocate them at will in the same process).
- Fast development lifecycle
- Simplified access to the database
PHP has become very popular lately and although I was not afraid of learning a new language (after all, it was one of the goals of this project), it did not feel like it was satisfying all my constraints (note that I may be wrong due to my lack of deep knowledge of this technology). Rapidly, I narrowed it down to ROR (Ruby on Rails) and Grails. I believe both frameworks are very similar in concept, both offering very fast turnaround, scaffolding, ORM layer...
My final decision to use Grails was motivated by the fact that the language used is Groovy and Groovy is java! So I knew I would not have too much trouble learning it and more importantly integrating with any java code or backend server would be a breeze. To bootstrap the process I read the two excellent books (which I strongly recommend): Groovy in Action and The Definitive Guide to Grails, Second Edition
.
After using Grails for several months, I am pretty happy with the choice. I have not used the ORM capabilities yet but I was able to successfully deploy my java backend services in the same VM (by wiring them directly in spring): the autowiring capabilities into the bootstrap sequence and the controllers made it a breeze. Working with controllers and gsp pages (equivalent to jsp for Grails) has been relatively painless and I certainly appreciate the ability to simply modify the source code and see the changes right away when refreshing the page in the browser (which satisfies the fast development lifecycle constraint). I really like the extensibility of the gsp layer by being able to write your own tag library (you can check my post about grails tag libraries): it is pretty straightforward and very powerful.
But in the end, the reason why I am really glad I made this choice is actually the Groovy language. I did not know it beforehand and I am very excited to add it to my toolbox. As I was mentioning before, Groovy is java. Groovy gets compiled into java and integrates seamlessly with it, which is huge for someone who knows java quite well. What it brings to java is big and when I go back to java, I always wish some of the features would be native to java: I love closures, duck typing and builders to name a few. Groovy allows you to be strongly typed if you want to, but unlike pure java, it is not enforced. There is always a battle between the two camps, but I prefer to be neutral and use whichever makes more sense in what I am currently working on.
// small example showing how concise and efficient the syntax can be
// duck typing in action:
// * this method will work on any object which has a method sort(Closure closure)
// * as long as the elements in the list knows how to handle '.name' it will work
// as well (which covers, properties, getters, and even maps (since map["name"]
// can be written map.name!))
static def sortByName(list)
{
list.sort() { e1, e2 ->
return e1.name.compareTo(e2.name)
}
}
Since my initial exposure to Groovy through Grails, I have actually started using it in other areas:
- For 'shell' scripts (which I used to write in bash, perl or python): you get all the power of java and groovy for writing small scripts so no need to switch to a totally different syntax.
- For testing: this is definitely an area where I really don't see any advantage in writing my unit tests in java anymore even if what I am testing is my java code. It is less code to write and it is more readable.
Grails - Invoking a tag lib from another tag lib
Grails comes with a predefined set of tags that you can use in your gsp pages. If you want to add your own tags, it is pretty simple and you can simply check the Dynamic Tag Libraries reference documentation. I created my own version of the <g:each> tag which allows you to provide a begin, end and separator attributes:
class MyTagLib {
static namespace = 'my'
// Equivalent to g:each but allow for begin/end and separator attributes
def each = { attrs, body ->
def var = attrs.var ?: "var"
def begin = attrs.begin ?: ""
def end = attrs.end ?: ""
def writer = out
if(attrs.in)
{
// not null and not empty (definition of truth in groovy)
attrs.in.eachWithIndex { elt, i ->
if(i == 0)
{
writer << begin
}
else
{
writer << attrs.separator
}
writer << body((var):elt)
}
writer << end
}
else
{
if(attrs.alwaysBeginEnd?.toString() == "true")
{
writer << begin << end
}
}
}
}
Here are some examples of rendering in gsp:
<my:each in="${[1,2,3]}" var="i">${i}</my:each>
produces: 123
<my:each in="${[1,2,3]}" var="i" begin="{" end="}" separator=",">${i}</my:each>
produces: {1,2,3}
<my:each in="${[1]}" var="i" begin="{" end="}" separator=",">${i}</my:each>
produces: {1}
<my:each in="${[]}" var="i" begin="{" end="}" separator=",">${i}</my:each>
produces:
<my:each in="${[]}" var="i" begin="{" end="}" separator="," alwaysBeginEnd="true">${i}</my:each>
produces: {}
This tag is pretty convenient as it automatically takes care of an empty list or one that has only one element to properly display the separator and the begin and end attributes. The last example shows how you can 'force' to display the begin and end attributes when the list is empty.
Now, let's say I want to create another tag which will reuse the code I already wrote. In other words, I need to call a tag from within a tag. Here is how I would do it:
def csv = { attrs, body ->
def var = attrs.var ?: "var"
out << my.each(in: attrs.in, var: 'v', separator: ',') { map ->
def elt = map.v
out << "{"
out << body((var):elt)
out << "}"
}
}
And here is the rendering in gsp:
<my:csv in="${[1,2,3]}" var="i">[${i}]</my:csv>
produces: {[1]},{[2]},{[3]}
It is actually not that trivial to call a tag from within a tag (and to my knowledge it is not documented)... let's cover each details:
- referencing another tag is used with the notation:
namespace.tagName(ex:my.each) - simply calling the other tag is not enough and the result must be sent to the writer (ex:
out << my.each(...)) - each attribute is passed in as a map, so you simply use the groovy map notation (ex:
(in: attrs.in, var: 'v', separator: ',')) - now the really tricky part is the closure which corresponds to the children tags in gsp... the argument that you get is a map (because in the
my.eachcode, thebodyclosure is called with a map!). Although it makes sense, it is not that trivial because in gsp you don't see it. This is why I need to usemap.vto have access to the element that is being iterated over (the variablevis because it is the one that I used in the call (my.each(..., var: 'v', ...)))
Although a little tricky to write, it is very powerful to be able to create tags that build upon other tags. There is one little caveat in how null is being handled and I opened a Jira ticket for it (GRAILS-4449) as it does not seem to be consistent.
Grails - Proper shutdown in dev mode
For my main project I am using Grails for the front-end (I will relate in an upcoming post why I chose this technology in the first place). Grails has this very interesting development mode which allows you to continue working on your application and see the changes right away. To start the application you usually issue the command:
grails run-appor if you use maven
mvn grails:run-appTo shutdown (for restarting for example), you do a
CTRL-C which terminates the process. Grails uses the Spring framework to bootstrap your application. It also allows you to define your own beans. However, I noticed that when terminating the application, the beans that I had registered with a destroy-method were not being properly shutdown (the destroy method is simply not called). I tried to find a way to change this behavior by default but did not find anything. I then implemented my own shutdown solution in this manner:
I created a simple class in grails-app/utils/com/mypackage/ShutdownHook.groovy which registers a VM-wide shutdown hook when it gets called by Spring (ApplicationContextAware)
package com.mypackage
import org.springframework.context.ApplicationContextAware
import org.springframework.context.ApplicationContext
import org.apache.commons.logging.Log
import org.apache.commons.logging.LogFactory
public class ShutdownHook implements ApplicationContextAware
{
public static final Log log = LogFactory.getLog(ShutdownHook.class)
public void setApplicationContext(ApplicationContext applicationContext)
{
Runtime.runtime.addShutdownHook {
log.info("Application context shutting down...")
applicationContext.close()
log.info("Application context shutdown.")
}
log.info("Shutdown hook setup...")
}
}
Then I added the following block in grails-app/conf/spring/resources.groovy which conditionally creates the bean only in development mode (thanks to groovy Spring DSL!).
if(grails.util.GrailsUtil.isDevelopmentEnv())
{
myShutdownHook(com.mypackage.ShutdownHook)
}
It works really well as my beans get properly destroyed when the application terminates. Nonetheless it would be better if it was part of the Grails framework by default. I opened a Jira (GRAILS-4404) ticket for it.
-
Search
-
Feed
-
Links
-
Recommendations
-
Recent Entries
- Connecting to a local vm using jmx knowing the process id.
- Configuring apache -> tomcat load balancer
- pongasoft presents... kiwidoc
- CSS for the UI design
- The real cost of high-speed internet in the US
- Grails/Groovy for the frontend
- OSGi at LinkedIn (EclipseCon 2009)
- Improving performances of a Lucene Search
- git for source control management
- Version Management and OSGi
- Grails - Invoking a tag lib from another tag lib
- Starting from scratch... domain name and web hosting
- Grails - Proper shutdown in dev mode
- pongasoft.... a new adventure
- Welcome to the software cookbook!
-
Calendar
