0

Grails :: Broken Mail Template Rendering

Ugg. So one thing all web applications HAVE to do is send mail. In order to keep your code tidy you should be using templates to handle your mail formatting. In PHP + Zend Framework I have accomplished this cleanly via the following:

1
2
3
4
5
6
7
8
9
10
11
12
$view = new Zend_View();
$view->addScriptPath(BASE_PATH.'/tpl');
$view->somevar = $somevar;
$html = $view->render('someTemplate.phtml');
 
$mail = new Zend_Mail();
$mail->setBodyHtml($html);
$mail->setFrom($config->site->serviceAddress, $config->site->appName);
$mail->addTo($email);
 
$mail->setSubject($config->site->appName.' - Message Subject');
$mail->send();

Zend_View handles the output buffering and rendering of the template. I have never really had a problem with it.

In Grails this is supposed to work:

1
2
3
4
5
6
sendMail {
	to user.email
        from 'email@emails.com'
        subject 'Subject'
        body (view:'/mail/myTemplate', model[user:user])
}

sendMail is a mail service plugin that accepts a closure as an argument, it also has a shortcut to the gsp template engine to render the template. Seems more simplistic, however there is a lot of code under the hood driving it. It seems that the output buffering within the Grails framework is very tied to the servlet response.

Anyway within a Grails Service (haven’t tried it within a controller yet) it munges the output buffer. Probably due to the output buffer juggling that is going on within various layers of the response and template rendering wrappers. The result is a failed remoting call.

The fix (figured this out after profiling and digging around the web) is to wrap sendMail in a thread:

1
2
3
4
5
6
7
8
9
def t = new Thread() {
	sendMail {
		to user.email
                from 'email@emails.com'
                subject 'Subject'
                body (view:'/mail/myTemplate', model[user:user])
	}
}
t.start()

This leads me to believe that somewhere within GrailsPageResponseWrapper the original output buffer is being overwritten or lost which is killing the response writer. Spawning a new thread for the operation preserves the original output buffer.

I am surprised that no one else is using this functionality outside of their controllers, and only 2 people have encountered the issue. I don’t know enough about the grails stack to debug it fully myself yet.

Here is a link to the bug report:
http://jira.codehaus.org/browse/GRAILSPLUGINS-1548

Please fix? :)

Read More