解决 Unable to compile class for JSP 问题

在使用jsp页面时,出现这个问题:

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

An error occurred at line: [29] in the generated java file: [/webapps/apache-tomcat8-dev/work/Catalina/localhost/ROOT/org/apache/jsp/index_jsp.java]
Type mismatch: cannot convert from HashSet<?> to Set<String>

An error occurred at line: [29] in the generated java file: [/webapps/apache-tomcat8-dev/work/Catalina/localhost/ROOT/org/apache/jsp/index_jsp.java]
Cannot instantiate the type HashSet<?>

An error occurred at line: [29] in the generated java file: [/webapps/apache-tomcat8-dev/work/Catalina/localhost/ROOT/org/apache/jsp/index_jsp.java]
Syntax error on token "<", ? expected after this token

    Stacktrace:
        org.apache.jasper.compiler.DefaultErrorHandler.javacError(DefaultErrorHandler.java:102)
        org.apache.jasper.compiler.ErrorDispatcher.javacError(ErrorDispatcher.java:198)
        org.apache.jasper.compiler.JDTCompiler.generateClass(JDTCompiler.java:450)
        org.apache.jasper.compiler.Compiler.compile(Compiler.java:361)
        org.apache.jasper.compiler.Compiler.compile(Compiler.java:336)
        org.apache.jasper.compiler.Compiler.compile(Compiler.java:323)
        org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:585)
        org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:363)
        org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:396)
        org.apache.jasper.servlet.JspServlet.service(JspServlet.java:340)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
        org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

解决方法:

       首先,查看Tomcat路径下的\lib文件夹,检查名为ecj-4.6.3的jar(可能会版本不同,但是我这个版本号没有问题),查看是否有其他版本的jar,如果有请删除低版本的jar,这会引起冲突而导致这个异常发生。如果还不可以请将你自己引入的jsp-api,以及servlet-api的pom依赖加上<scope>provided</scope>。

 

 

 

报错异常信息解释:

       异常中报出的HashSet   是jsp被编译成.java文件后所产生的Java文件,而错误就是在将.Java文件生成.class文件时出现的。因为jar冲突 所以.class文件无法被生成。  这个HashSet是用来放置jsp页面所引入的包,以及jsp依赖的jar信息。如下图所示,所以报出的错误与自己的代码并没有关系。

Maven 中 scope的解释:

对于scope=compile的情况(默认scope),也就是说这个项目在编译,测试,运行阶段都需要这个artifact(模块)对应的jar包在classpath中。 
而对于scope=provided的情况,则可以认为这个provided是目标容器已经provide这个artifact。换句话说,它只影响到编译,测试阶段。在编译测试阶段,我们需要这个artifact对应的jar包在classpath中,而在运行阶段,假定目标的容器(比如我们这里的liferay容器)已经提供了这个jar包,所以无需我们这个artifact对应的jar包了。       

          因为Tomcat自带有jsp-api,以及servlet-api依赖,为了防止自己引入的pom与Tomcat自带依赖冲突,可以使用<scope>provided</scope>使自己的pom依赖不参与运行。其实项目在启动时,会先加载用户自己的jar,然后再加载Tom的依赖。

 

希望这篇文章可以帮到你解决问题....