grails / grails-mail

The Grails Mail Plugin
https://grails.github.io/grails-mail/
Apache License 2.0
14 stars 25 forks source link

Unable to use body method variant with model in Grails 3.0.7 and earlier #16

Closed rlovtangen closed 4 years ago

rlovtangen commented 8 years ago

Using body with model does not work in Grails 3.0.7 and earlier with mail plugin 2.0.0.RC6 as opposed to 2.0.0.RC4.

Example:

class FooController {
    def mailService

    def mail() {
        mailService.sendMail {
            to "john@g2one.com"
            subject "Hello John"
            body(view: "/foo/index",
                    model: [bar: 'foobar']
            )       
        }
        render "ok"
    }
}

Exception:

ERROR org.grails.web.errors.GrailsExceptionResolver - NoSuchMethodError occurred when processing request: [GET] /foo/mail
org.grails.gsp.GroovyPageTemplate.make(Ljava/util/Map;)Lorg/grails/gsp/GroovyPageWritable;. Stacktrace follows:
java.lang.reflect.InvocationTargetException: null
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_31]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_31]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_31]
Caused by: java.lang.NoSuchMethodError: org.grails.gsp.GroovyPageTemplate.make(Ljava/util/Map;)Lorg/grails/gsp/GroovyPageWritable;
    at grails.plugins.mail.MailMessageContentRenderer$_render_closure1.doCall(MailMessageContentRenderer.groovy:60) ~[mail-2.0.0.RC6.jar:na]
    at grails.plugins.mail.MailMessageContentRenderer$RenderEnvironment.with(MailMessageContentRenderer.groovy:174) ~[mail-2.0.0.RC6.jar:na]
    at grails.plugins.mail.MailMessageContentRenderer.render(MailMessageContentRenderer.groovy:57) ~[mail-2.0.0.RC6.jar:na]
    at grails.plugins.mail.MailMessageBuilder.doRender(MailMessageBuilder.groovy:276) ~[mail-2.0.0.RC6.jar:na]
    at grails.plugins.mail.MailMessageBuilder.body(MailMessageBuilder.groovy:258) ~[mail-2.0.0.RC6.jar:na]
    at wkapp.FooController$_mail_closure2.doCall(FooController.groovy:37) ~[main/:na]
    at grails.plugins.mail.MailService.sendMail(MailService.groovy:51) ~[mail-2.0.0.RC6.jar:na]
    at grails.plugins.mail.MailService.sendMail(MailService.groovy:57) ~[mail-2.0.0.RC6.jar:na]
    at wkapp.FooController.mail(FooController.groovy:34) ~[main/:na]
    ... 3 common frames omitted

This is caused by template.make(model).writeTo(out) in MailMessageContentRender.render.

MailMessageContentRender render(Writer out, String templateName, Map model, Locale locale, String pluginName = null) {
        RenderEnvironment.with(grailsApplication.mainContext, out, locale) { RenderEnvironment env ->
            Template template = createTemplate(templateName, env.controllerName, pluginName)
            if (model instanceof Map) {
                template.make(model).writeTo(out)
            } else {
                template.make().writeTo(out)
            }

            new MailMessageContentRender(out, template.metaInfo.contentType)
        } as MailMessageContentRender
    }

Without body as parameter, the other part of the if-statement, template.make().writeTo(out), is invoked, which works fine also in Grails 3.0.7.

rlovtangen commented 8 years ago

The return type of GroovyPageTemplate.make(Map binding) has been changed in Grails 3.0.8 from Writable to GroovyPageWritable (https://github.com/grails/grails-core/commit/932177e21a0fb21faec431c6cde43209f8a85b53) This in conjunction with the CompileStatic changes in 2.0.0.RC6 might cause this issue? Note that 2.0.0.RC4 works fine, so it's not the changes in grails-core alone.

erichelgeson commented 4 years ago

I believe this works in the latest versions. Please feel free to make a new issue if not.