• 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。

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

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

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

    /*
     * 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.
     */
    package org.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 implements org.apache.jasper.runtime.JspSourceDependent {
    
        private static final javax.servlet.jsp.JspFactory                _jspxFactory    = javax.servlet.jsp.JspFactory.getDefaultFactory();
    
        private static java.util.Map<java.lang.String, java.lang.Long>    _jspx_dependants;
    
        static {
            _jspx_dependants = new java.util.HashMap<java.lang.String, java.lang.Long>(1);
            _jspx_dependants.put("/browse/part/cache-control-header.jsp", Long.valueOf(1488337979237L));
        }
    
        private static final java.util.Set<java.lang.String>    _jspx_imports_packages;
    
        private static final java.util.Set<java.lang.String>    _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 volatile javax.el.ExpressionFactory            _el_expressionfactory;
        private volatile org.apache.tomcat.InstanceManager    _jsp_instancemanager;
    
        public java.util.Map<java.lang.String, java.lang.Long> getDependants() {
            return _jspx_dependants;
        }
    
        public java.util.Set<java.lang.String> getPackageImports() {
            return _jspx_imports_packages;
        }
    
        public java.util.Set<java.lang.String> getClassImports() {
            return _jspx_imports_classes;
        }
    
        public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
            if (_el_expressionfactory == null) {
                synchronized (this) {
                    if (_el_expressionfactory == null) {
                        _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
                    }
                }
            }
            return _el_expressionfactory;
        }
    
        public org.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, final javax.servlet.http.HttpServletResponse response)
                throws java.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;
            }
    
            final javax.servlet.jsp.PageContext pageContext;
            javax.servlet.http.HttpSession session = null;
            final javax.servlet.ServletContext application;
            final javax.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("<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    ");
                out.write("
    ");
                out.write("
    ");
                out.write("
    ");
    
                response.setHeader("Pragma", "No-cache");
                response.setHeader("Cache-Control", "no-cache");
                response.setDateHeader("Expires", 0);
    
                out.write('
    ');
                out.write('
    ');
    
                String errMsg = "";
                if (request.getAttribute("errMsg") != null) {
                    errMsg = request.getAttribute("errMsg").toString();
                }
    
                String RndData = "";
                int nRndLen;
                char Upper = '9';
                char Lower = '0';
                Random r = new Random();
                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 instanceof javax.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 new ServletException(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解析模板引擎。

  • 相关阅读:
    python数据类型以及模块的含义
    python基础语言以及if/while语句结构
    subprocess模块
    linux 管道通信socket 全双工示例
    整体框架
    licode_WebrtcConnection
    webrtc杂谈(转)
    修改背景颜色
    激活NX窗口的按钮
    NX屏蔽窗口的按钮
  • 原文地址:https://www.cnblogs.com/mahuan2/p/6485147.html
Copyright © 2020-2023  润新知