Jun 11, 2013

A Tale From the Grails trenches: Nasty 1.3.X Bug

grails_icon

Note: If this post help just one other person avoid the daylong head scratching session I recently went through It will be worth it.

It all starts early on a Monday moring. Just as I’m sitting down to start on what I had ‘planned’ to work on that day, my technical manager comes over and merely says to me:

Page XYZ was throwing errors all weekend.

bounce the server and it seems to be fixed, but can you look into it?

At this point 3 things go through my mind:

  1. There had not been any new code deployed to Production in over 3 weeks.
  2. It’s never a good sign when cycling a production server is the solution to any problem
  3. I need to stop being the first developer in on Mondays 🙂

After a half hour of looking at log files and trying to reproduce it on my local machine I came across this error:

org.codehaus.groovy.grails.web.taglib.exceptions.GrailsTagException: Tag [render]   is missing required attribute [template]

at com.bug.TestController$_closure2.doCall(TestController.groovy:12)

at com.bug.TestController$_closure2.doCall(TestController.groovy)

at java.lang.Thread.run(Thread.java:680)

This was very odd to me. Why was a GrailsTagException being thrown from my Contrller class? I know that you can invoke the GrailsTagLibs in a controller via the g attribute that gets injected, but my code was NOT using that.

Here is the code that was throwing the error:

try{
    def result = doSomething()
    render result as JSON
} catch(Exception ex) {
    def error = [error: 'There was an error""]
    render error as JSON, status: 503
}

Can you spot the error? Let’s look closely at this line in the catch block:

render error as JSON, status: 503

The render method on controllers have 2 main method signatures that you can use, one that takes a single param that can be something that you can write to the response like a simple string, or XML, or JSON. Another is one that takes a map, that can include: text, status, contentType, template, etc, all of which is marked as optional [render doc]

But our error message is saying that the template attribute is required?

If you look closely our suspect line of code above is trying to call a render method with as signature of:

render(JsonConverter, LinkedHashMap)

and this does not exist. So because this method does not exist, and we have all the power of Groovy at our disposal; the magic of method missing comes in to play and tries to go find a render method to match this description. Finally it comes to the g.render() method that is available via the GrailsTagLib.

Boom! This is where things go badly

Once Grails finds the render method on the Grails Tag Lib, which is a completly separate chunk of code from the controller render method, it then binds the TagLib render to ALL future calls to render on EVERY controller.

And because the template attribute is required in the Tag Lib version of render any call to render on any controller that dosn’t pass in a ‘template’ attribute will die a fiery death with a GrailsTagException.

The good news it that this bug has been addressed in Grails 2.x and above. I hope you never have to experience this one yourself but if you are stuck on the 1.3.x branch and do, I hope this post servers you well.

Here is a sample project that reproduces this issue in Grails 1.3.9 GitHub

 

About the Author

Object Partners profile.

One thought on “A Tale From the Grails trenches: Nasty 1.3.X Bug

  1. mike says:

    Thanks for sharing!

    1. Zan Thrash says:

      Lauri H

      The project I was on at the time was a fairly large multi-app system where the ROI on upgrading to 2.x was not there for the business.

Leave a Reply

Your email address will not be published.

Related Blog Posts
A security model for developers
Software security is more important than ever, but developing secure applications is more confusing than ever. TLS, mTLS, RBAC, SAML, OAUTH, OWASP, GDPR, SASL, RSA, JWT, cookie, attack vector, DDoS, firewall, VPN, security groups, exploit, […]
Building Better Data Visualization Experiences: Part 1 of 2
Through direct experience with data scientists, business analysts, lab technicians, as well as other UX professionals, I have found that we need a better understanding of the people who will be using our data visualization products in order to build them. Creating a product utilizing data with the goal of providing insight is fundamentally different from a typical user-centric web experience, although traditional UX process methods can help.
Kafka Schema Evolution With Java Spring Boot and Protobuf
In this blog I will be demonstrating Kafka schema evolution with Java, Spring Boot and Protobuf.  This app is for tutorial purposes, so there will be instances where a refactor could happen. I tried to […]
Redis Bitmaps: Storing state in small places
Redis is a popular open source in-memory data store that supports all kinds of abstract data structures. In this post and in an accompanying example Java project, I am going to explore two great use […]