从Tomcat 8.0.x升级到8.5.30后Gradle构建因JasperException失败求助
解决Tomcat 8.5.30升级后Gradle TomcatJasper任务引号报错问题
这个问题我之前帮朋友排查过,Tomcat 8.5.x版本的Jasper(JSP编译器)在语法规范上比8.0.x严格了很多,尤其是对引号的使用检查,咱们一步步来解决:
1. 先定位报错的具体JSP文件
根据报错信息里的xxx找到对应的JSP文件,重点检查以下几种引号问题:
- EL表达式中的嵌套引号:比如
${someMap["keyName"]}这种写法,Tomcat 8.5可能会判定为不规范,建议改成${someMap.keyName},或者把双引号换成单引号${someMap['keyName']} - HTML属性与JSP表达式的引号冲突:比如
<input value="<%= user.getName() %>">,如果user.getName()返回的字符串本身包含双引号,就会导致语法错误,需要在代码里对输出的字符串做转义处理(比如用StringEscapeUtils.escapeHtml4()) - JSP标签属性的引号嵌套错误:比如
<c:set var="msg" value="Hello "World""这种明显未闭合的双引号,直接修正为<c:set var="msg" value='Hello "World"'或者转义内部双引号<c:set var="msg" value="Hello \"World\""
2. 调整Gradle TomcatJasper任务的编译参数
如果暂时不想修改JSP代码,可以在build.gradle的convertToJavaFromJSP任务中添加编译器参数,关闭严格的引号检查或者设置兼容模式:
task convertToJavaFromJSP(type: com.bmuschko.gradle.tomcat.tasks.TomcatJasper) { uriroot = file("${project.webAppDirName}") outputDir = file("${project.ext.precompileDir}") classpath = configurations.precompile + sourceSets.main.output + sourceSets.main.runtimeClasspath // 添加编译器参数,兼容Tomcat 8.0的语法检查 compilerOptions { // 根据项目实际JDK版本调整source和target source = "1.8" target = "1.8" // 关闭严格的引号转义检查 addArg("-strictQuoteEscaping", "false") // 指定JVM编译版本,确保和项目一致 addArg("-compilerSourceVM", "1.8") addArg("-compilerTargetVM", "1.8") } }
-strictQuoteEscaping是Jasper的核心参数,Tomcat 8.5默认开启了严格检查,而8.0版本默认是关闭的,添加这个参数可以让编译器回到8.0的宽松模式。
3. 确保Gradle Tomcat插件版本兼容Tomcat 8.5
如果你使用的是com.bmuschko.tomcat插件,旧版本可能对Tomcat 8.5的Jasper支持不足,建议升级插件版本到2.7.0及以上:
plugins { id 'com.bmuschko.tomcat' version '2.7.0' }
这个版本的插件已经适配了Tomcat 8.5的API和编译参数,能避免很多兼容性问题。
4. 手动用Jasper编译验证(可选)
如果还是找不到问题,可以用Tomcat自带的Jasper工具手动编译JSP,获取更详细的错误信息:
# 进入Tomcat的bin目录 cd /path/to/tomcat-8.5.30/bin # 编译指定webapp的JSP java -cp "../lib/*" org.apache.jasper.JspC -webapp /path/to/your/project/src/main/webapp -d /tmp/jsp-compile-output -strictQuoteEscaping false
执行后会输出具体的错误行号和原因,方便精准定位修复。
内容的提问来源于stack exchange,提问作者Destiny
相关产品推荐
相关产品推荐

