embedded java_embedded tomcat运行java web,Unable to compile class for JSP

环境

eclipse:4.5.2

jre:1.8

java project compiler:1.8

embedded tomcat:7.0.32

可以正常启动,但是访问时,会报错。

HTTP Status 500 - Unable to compile class for JSP:

type Exception report

message Unable to compile class for JSP:

description The server encountered an internal error that prevented it from fulfilling this request.

exception

org.apache.jasper.JasperException: Unable to compile class for JSP:

An error occurred at line: 1 in the generated java file

The type java.util.Map$Entry cannot be resolved. It is indirectly referenced from required .class files

An error occurred at line: 1 in the generated java file

The type java.io.ObjectInputStream cannot be resolved. It is indirectly referenced from required .class files

Stacktrace:

org.apache.jasper.compiler.DefaultErrorHandler.javacError(DefaultErrorHandler.java:102)

org.apache.jasper.compiler.ErrorDispatcher.javacError(ErrorDispatcher.java:331)

org.apache.jasper.compiler.JDTCompiler.generateClass(JDTCompiler.java:469)

org.apache.jasper.compiler.Compiler.compile(Compiler.java:378)

org.apache.jasper.compiler.Compiler.compile(Compiler.java:353)

org.apache.jasper.compiler.Compiler.compile(Compiler.java:340)

org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:646)

org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:357)

org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)

org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)

javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:123)

note The full stack trace of the root cause is available in the Apache Tomcat/7.0.32 logs.

Apache Tomcat/7.0.32

内容摘要就是jsp转换成java文件,java文件编译成class文件时报错。根据标红部分指示的信息,开始以为是未引用类造成的,检查了jsp文件没有任何问题。

通过搜索引擎,发现出现jsp无法编译,有各种各样的原因。比如servlet-api在应用中有一份,tomcat中有一份,二者不是一个版本,报错了;或者jsp文件本身就有语法错误。

最后调试发现,具体错误和上面标红的字体有所不同。

在jsp翻译的java文件进行编译时,CompilerSourceVM值为1.6,CompilerTargetVM也是1.6,即将jsp翻译的java文件,以符合1.6 java语法约束的java,编译为可在1.6 jre中运行的class。

ddb09060a9618c13a2e51013f482c2d6.png

cfd8953073b028589ee5db843ced3cdd.png

而jsp翻译成java的文件内容如下所示,注意

_jspx_imports_packages = new java.util.HashSet<>();

此种方式的泛型使用,在版本号小于1.7的jdk中是错误的,小于1.7版本的java约束中,要求必须将泛型类型写上的,不能为空,因此文件约束就过不了,自然无法compile成1.6版本的class文件,自然就报错了。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

/** Generated by the Jasper component of Apache Tomcat

* Version: Apache Tomcat/8.5.9

* Generated at: 2017-03-01 08:22:23 UTC

* Note: The last modified time of this file was set to

* the last modified time of the source file after

* generation to assist with modification tracking.*/

packageorg.apache.jsp;import javax.servlet.*;import javax.servlet.http.*;import javax.servlet.jsp.*;import java.util.*;public final class default_jsp extends org.apache.jasper.runtime.HttpJspBase implementsorg.apache.jasper.runtime.JspSourceDependent {private static final javax.servlet.jsp.JspFactory _jspxFactory =javax.servlet.jsp.JspFactory.getDefaultFactory();private static java.util.Map_jspx_dependants;static{

_jspx_dependants= new java.util.HashMap(1);

_jspx_dependants.put("/browse/part/cache-control-header.jsp", Long.valueOf(1488337979237L));

}private static final java.util.Set_jspx_imports_packages;private static final java.util.Set_jspx_imports_classes;static{

_jspx_imports_packages= new java.util.HashSet<>();

_jspx_imports_packages.add("javax.servlet");

_jspx_imports_packages.add("java.util");

_jspx_imports_packages.add("javax.servlet.http");

_jspx_imports_packages.add("javax.servlet.jsp");

_jspx_imports_classes= null;

}private volatilejavax.el.ExpressionFactory _el_expressionfactory;private volatileorg.apache.tomcat.InstanceManager _jsp_instancemanager;public java.util.MapgetDependants() {return_jspx_dependants;

}public java.util.SetgetPackageImports() {return_jspx_imports_packages;

}public java.util.SetgetClassImports() {return_jspx_imports_classes;

}publicjavax.el.ExpressionFactory _jsp_getExpressionFactory() {if (_el_expressionfactory == null) {synchronized (this) {if (_el_expressionfactory == null) {

_el_expressionfactory=_jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();

}

}

}return_el_expressionfactory;

}publicorg.apache.tomcat.InstanceManager _jsp_getInstanceManager() {if (_jsp_instancemanager == null) {synchronized (this) {if (_jsp_instancemanager == null) {

_jsp_instancemanager=org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());

}

}

}return_jsp_instancemanager;

}public void_jspInit() {

}public void_jspDestroy() {

}public void _jspService(final javax.servlet.http.HttpServletRequest request, finaljavax.servlet.http.HttpServletResponse response)throwsjava.io.IOException, javax.servlet.ServletException {final java.lang.String _jspx_method =request.getMethod();if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)&& !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {

response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED,"JSPs only permit GET POST or HEAD");return;

}finaljavax.servlet.jsp.PageContext pageContext;

javax.servlet.http.HttpSession session= null;finaljavax.servlet.ServletContext application;finaljavax.servlet.ServletConfig config;

javax.servlet.jsp.JspWriter out= null;final java.lang.Object page = this;

javax.servlet.jsp.JspWriter _jspx_out= null;

javax.servlet.jsp.PageContext _jspx_page_context= null;try{

response.setContentType("text/html; charset=utf-8");

pageContext= _jspxFactory.getPageContext(this, request, response, "errorReport.jsp", true, 8192, true);

_jspx_page_context=pageContext;

application=pageContext.getServletContext();

config=pageContext.getServletConfig();

session=pageContext.getSession();

out=pageContext.getOut();

_jspx_out=out;

out.write(""-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\r\n");

out.write("\r\n");

out.write("\r\n");

out.write("\r\n");

response.setHeader("Pragma", "No-cache");

response.setHeader("Cache-Control", "no-cache");

response.setDateHeader("Expires", 0);

out.write('\r');

out.write('\n');

String errMsg= "";if (request.getAttribute("errMsg") != null) {

errMsg= request.getAttribute("errMsg").toString();

}

String RndData= "";intnRndLen;char Upper = '9';char Lower = '0';

Random r= newRandom();for (int i = 0; i < 15; i++) {int tempval = (int) ((int) Lower + (r.nextFloat() * ((int) (Upper -Lower))));

RndData+= new Character((char) tempval).toString();

}

session.setAttribute("RandomData", RndData);

nRndLen=RndData.length();//输出html内容,为了省略篇幅,删去

} catch(java.lang.Throwable t) {if (!(t instanceofjavax.servlet.jsp.SkipPageException)) {

out=_jspx_out;if (out != null && out.getBufferSize() != 0)try{if(response.isCommitted()) {

out.flush();

}else{

out.clearBuffer();

}

}catch(java.io.IOException e) {

}if (_jspx_page_context != null)

_jspx_page_context.handlePageException(t);else

throw newServletException(t);

}

}finally{

_jspxFactory.releasePageContext(_jspx_page_context);

}

}

}

View Code

解决方法

1、通过更换embedded tomcat的版本到8.5.9(未测试最低版本是多少),此时CompilerSourceVM和CompilerTargetVM的值全部升到了1.7,再次运行,jsp文件顺利编译为class,程序运行不报错。

2、项目组其他人员验证,未本人验证。使用ide的server功能,server版本是tomcat 6即可。

额外发现

在embedded tomcat中,jasper会将将要访问的jsp文件,转换为java文件,然后再编译为class文件,最后再运行。

一直以为jsp文件是动态解析的,有一个专门的jsp解析模板引擎。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值