-
-
Notifications
You must be signed in to change notification settings - Fork 967
Closed
Description
In previous versions of Grails it was possible to generate templates on a background thread (things like emails, etc) for async generation. I'm not exactly sure which version this broke in.
A simple method like this:
String renderTemplate(String key, String content, Map model) {
Template template = groovyPagesTemplateEngine.createTemplate(content, key)
Writable renderedTemplate = template.make(model);
StringWriter stringWriter = new StringWriter();
renderedTemplate.writeTo(stringWriter);
return stringWriter.toString();
}
Example call:
String template = renderTemplate("myTemplateId", '<h3>Hello, ${user} </h3>', [user: "Grails User"]);
Doing this on a background thread, causes the exception below. Looks like it relates to the WebOutputContext - however as you can see in my template generation this should have no dependency on a web context.
Steps to Reproduce
- Clone https://github.com/donald-jackson/grails-template-error3211.git
- Run-app
- Visit http://localhost:8080/example/background
- Visit http://localhost:8080/example/foreground - same code but on foreground thread, renders out the template.
Expected Behaviour
No exceptions, a template is rendered in the background
Actual Behaviour
java.lang.NullPointerException: null
at org.grails.web.taglib.encoder.WebOutputContextLookup$WebOutputContext.getBinding(WebOutputContextLookup.java:89)
at org.grails.gsp.GroovyPageWritable.doWriteTo(GroovyPageWritable.java:112)
at org.grails.gsp.GroovyPageWritable.writeTo(GroovyPageWritable.java:82)
at groovy.lang.Writable$writeTo$0.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
at grails.template.demo.TemplateService.$tt__renderTemplate(TemplateService.groovy:20)
at grails.template.demo.TemplateService$_renderTemplate_closure1.doCall(TemplateService.groovy)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1426)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
at groovy.lang.Closure.call(Closure.java:414)
at groovy.lang.Closure.call(Closure.java:430)
at grails.transaction.GrailsTransactionTemplate$2.doInTransaction(GrailsTransactionTemplate.groovy:96)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
at grails.transaction.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:93)
at grails.template.demo.TemplateService.renderTemplate(TemplateService.groovy)
at grails.template.demo.TemplateService$renderTemplate$0.callCurrent(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:52)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:154)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:182)
at grails.template.demo.TemplateService.$tt__backgroundTask(TemplateService.groovy:26)
at grails.template.demo.TemplateService$_backgroundTask_closure2.doCall(TemplateService.groovy)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1426)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
at groovy.lang.Closure.call(Closure.java:414)
at groovy.lang.Closure.call(Closure.java:430)
at grails.transaction.GrailsTransactionTemplate$2.doInTransaction(GrailsTransactionTemplate.groovy:96)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
at grails.transaction.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:93)
at grails.template.demo.TemplateService.backgroundTask(TemplateService.groovy)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1426)
at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:216)
at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:201)
at reactor.spring.context.config.ConsumerBeanAutoConfiguration$Invoker.apply(ConsumerBeanAutoConfiguration.java:333)
at reactor.spring.context.config.ConsumerBeanAutoConfiguration$ServiceConsumer.accept(ConsumerBeanAutoConfiguration.java:297)
at reactor.spring.context.config.ConsumerBeanAutoConfiguration$ServiceConsumer.accept(ConsumerBeanAutoConfiguration.java:284)
at reactor.bus.EventBus$3.accept(EventBus.java:317)
at reactor.bus.EventBus$3.accept(EventBus.java:310)
at reactor.bus.routing.ConsumerFilteringRouter.route(ConsumerFilteringRouter.java:72)
at reactor.bus.EventBus.accept(EventBus.java:591)
at reactor.bus.EventBus.accept(EventBus.java:63)
at reactor.core.dispatch.AbstractLifecycleDispatcher.route(AbstractLifecycleDispatcher.java:160)
at reactor.core.dispatch.MultiThreadDispatcher$MultiThreadTask.run(MultiThreadDispatcher.java:74)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: reactor.core.support.Exceptions$ValueCause: Exception while signaling value: reactor.bus.Event.class : Event{id=null, headers=null, replyTo=null, key=background.task, data={}}
at reactor.core.support.Exceptions.addValueAsLastCause(Exceptions.java:127)
at reactor.bus.routing.ConsumerFilteringRouter.route(ConsumerFilteringRouter.java:77)
... 7 common frames omitted
Environment Information
- Operating System: Mac OS X 10.12
- Grails Version: 3.2.11
- JDK Version: 1.8.0_111
Example Application
demon101
Metadata
Metadata
Assignees
Labels
No labels