Grails资产管道导致服务器错误

问题描述:

我创建了一个Grails应用程序,没有使用通过Tomcat使用Tomcat部署的自定义控制器.该应用程序可以在本地计算机上正常运行(运行应用程序和运行时),但是当我使用Tomcat进行部署时无法运行.

I have created a Grails app with no custom controllers that I have deployed using a Tomcat via Docker. The app runs ok (run-app and run-war) on my local machine, but not when I deploy using Tomcat.

我得到以下堆栈跟踪信息,请问原因原因?

I get the following stack trace, any idea of the cause please?

2014-10-17 08:08:04,158 [http-bio-8080-exec-10] ERROR StackTrace  - Full Stack Trace:
org.codehaus.groovy.grails.web.pages.exceptions.GroovyPagesException: Error applying layout : main
    at org.codehaus.groovy.grails.web.servlet.view.GroovyPageView.rethrowRenderException(GroovyPageView.java:179)
    at org.codehaus.groovy.grails.web.sitemesh.SpringMVCViewDecorator.render(SpringMVCViewDecorator.java:78)
    at org.codehaus.groovy.grails.web.sitemesh.GrailsLayoutView.renderTemplate(GrailsLayoutView.java:60)
    at org.codehaus.groovy.grails.web.servlet.view.AbstractGrailsView.renderWithinGrailsWebRequest(AbstractGrailsView.java:49)
    at org.codehaus.groovy.grails.web.servlet.view.AbstractGrailsView.renderMergedOutputModel(AbstractGrailsView.java:33)
    at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:267)
    at org.codehaus.groovy.grails.web.servlet.ErrorHandlingServlet.doDispatch(ErrorHandlingServlet.java:163)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
    at javax.servlet.http.HttpServlet.doHead(HttpServlet.java:243)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:643)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:69)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:748)
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:488)
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:411)
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:338)
    at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:466)
    at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:337)
    at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:427)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:200)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.codehaus.groovy.grails.web.pages.exceptions.GroovyPagesException: Error processing GroovyPageView: No signature of method: gsp_gradleGrailsApp_layoutsmain_gsp.assetPath() is applicable for argument types: (java.util.LinkedHashMap) values: [[src:favicon.ico]]
    at org.codehaus.groovy.grails.web.servlet.view.GroovyPageView.createGroovyPageException(GroovyPageView.java:127)
    at org.codehaus.groovy.grails.web.servlet.view.GroovyPageView.handleException(GroovyPageView.java:104)
    at org.codehaus.groovy.grails.web.servlet.view.GroovyPageView.renderTemplate(GroovyPageView.java:75)
    at org.codehaus.groovy.grails.web.servlet.view.AbstractGrailsView.renderWithinGrailsWebRequest(AbstractGrailsView.java:49)
    at org.codehaus.groovy.grails.web.servlet.view.AbstractGrailsView.renderMergedOutputModel(AbstractGrailsView.java:33)
    at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:267)
    at org.codehaus.groovy.grails.web.sitemesh.SpringMVCViewDecorator.render(SpringMVCViewDecorator.java:69)
    ... 36 more
Caused by: groovy.lang.MissingMethodException: No signature of method: gsp_gradleGrailsApp_layoutsmain_gsp.assetPath() is applicable for argument types: (java.util.LinkedHashMap) values: [[src:favicon.ico]]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:77)
    at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:102)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:198)
    at org.codehaus.groovy.grails.web.pages.GroovyPagesMetaUtils.methodMissingForTagLib(GroovyPagesMetaUtils.groovy:68)
    at org.codehaus.groovy.grails.web.pages.GroovyPagesMetaUtils$_registerMethodMissingForGSP_closure1.doCall(GroovyPagesMetaUtils.groovy:40)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaMethod.invoke(ClosureMetaMethod.java:80)
    at groovy.lang.MetaClassImpl.invokeMissingMethod(MetaClassImpl.java:933)
    at groovy.lang.MetaClassImpl.invokePropertyOrMissing(MetaClassImpl.java:1256)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1209)
    at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1110)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1016)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1111)
    at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1110)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1016)
    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:66)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
    at gsp_gradleGrailsApp_layoutsmain_gsp$_run_closure1.doCall(gsp_gradleGrailsApp_layoutsmain_gsp.groovy:31)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:324)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1207)
    at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1110)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1016)
    at groovy.lang.Closure.call(Closure.java:423)
    at groovy.lang.Closure.call(Closure.java:417)
    at org.codehaus.groovy.grails.web.taglib.GroovyPageTagBody.executeClosure(GroovyPageTagBody.java:206)
    at org.codehaus.groovy.grails.web.taglib.GroovyPageTagBody.captureClosureOutput(GroovyPageTagBody.java:108)
    at org.codehaus.groovy.grails.web.taglib.GroovyPageTagBody.call(GroovyPageTagBody.java:219)
    at org.codehaus.groovy.grails.plugins.web.taglib.SitemeshTagLib.captureTagContent(SitemeshTagLib.groovy:49)
    at org.codehaus.groovy.grails.plugins.web.taglib.SitemeshTagLib.captureTagContent(SitemeshTagLib.groovy)
    at org.codehaus.groovy.grails.plugins.web.taglib.SitemeshTagLib$_closure1.doCall(SitemeshTagLib.groovy:125)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:324)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1207)
    at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1110)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1016)
    at groovy.lang.Closure.call(Closure.java:423)
    at org.codehaus.groovy.grails.web.pages.GroovyPage.invokeTagLibClosure(GroovyPage.java:501)
    at org.codehaus.groovy.grails.web.pages.GroovyPage.invokeTag(GroovyPage.java:419)
    at org.codehaus.groovy.grails.web.pages.GroovyPage$invokeTag$4.callCurrent(Unknown Source)
    at gsp_gradleGrailsApp_layoutsmain_gsp.run(gsp_gradleGrailsApp_layoutsmain_gsp.groovy:44)
    at org.codehaus.groovy.grails.web.pages.GroovyPageWritable.doWriteTo(GroovyPageWritable.java:217)
    at org.codehaus.groovy.grails.web.pages.GroovyPageWritable.writeTo(GroovyPageWritable.java:128)
    at org.codehaus.groovy.grails.web.servlet.view.GroovyPageView.renderTemplate(GroovyPageView.java:71)
    ... 40 more

编辑后包含main.gsp列表:

EDITED to include main.gsp listing:

<!DOCTYPE html>
<!--[if lt IE 7 ]> <html lang="en" class="no-js ie6"> <![endif]-->
<!--[if IE 7 ]>    <html lang="en" class="no-js ie7"> <![endif]-->
<!--[if IE 8 ]>    <html lang="en" class="no-js ie8"> <![endif]-->
<!--[if IE 9 ]>    <html lang="en" class="no-js ie9"> <![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--> <html lang="en" class="no-js"><!--<![endif]-->
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <title><g:layoutTitle default="Grails"/></title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="shortcut icon" href="${assetPath(src: 'favicon.ico')}" type="image/x-icon">
        <link rel="apple-touch-icon" href="${assetPath(src: 'apple-touch-icon.png')}">
        <link rel="apple-touch-icon" sizes="114x114" href="${assetPath(src: 'apple-touch-icon-retina.png')}">
        <asset:stylesheet src="application.css"/>
        <asset:javascript src="application.js"/>
        <g:layoutHead/>
    </head>
    <body>
        <div id="grailsLogo" role="banner"><a href="http://grails.org"><asset:image src="grails_logo.png" alt="Grails"/></a></div>
        <g:layoutBody/>
        <div class="footer" role="contentinfo"></div>
        <div id="spinner" class="spinner" style="display:none;"><g:message code="spinner.alt" default="Loading&hellip;"/></div>
    </body>
</html>

啊,找到了.问题在于,部署时该项目是由Gradle Grails插件构建的.他们的文档中只有一个衬里( Gradle Grails插件):

Ahhh, found it. The issue is that the project is being built by the Gradle Grails plugin when deploying. There is a one liner in their docs (Gradle Grails plugin):

使用Grails Gradle插件会绕过正常的Grails应用程序 建立有利于Gradle的框架.其结果是 不再咨询BuildConfig.groovy的存储库或 依赖性信息.

Using the Grails Gradle Plugin bypasses the normal Grails application build framework in favor of Gradle. The consequence of this is that the BuildConfig.groovy is no longer consulted for repository or dependency information.

因此,将忽略BuildConfig.groovy中包含的插件,并使用build.gradle中定义的插件(不包括资产管道插件)来构建它.因此,"grails run-war"创建的战争文件不同于"gradle war"创建的战争文件.解压缩2个war文件显示出结构上的差异.将依赖关系从BuildConfig.groovy移至build.gradle意味着war文件已正确构建.

Therefore plugins that were being included from BuildConfig.groovy are being ignored and it was being built using the plugins defined in build.gradle (which did not include the asset pipeline plugin). Thus the war file being created by 'grails run-war' was different to that created by 'gradle war'. Unzipping the 2 war files showed the difference in structure. Moving the dependencies from BuildConfig.groovy to build.gradle meant the war file was built correctly.

感谢@JoshuaMoore的初步提示,这就是让我走上正轨的原因.

Thanks to @JoshuaMoore for the initial hint, that's what put me on the right track.