In order to compile JSPs with Java 8, I made the following additions to the JSP servlet in conf\web.xml: <init-param> <param-name>compiler</param-name> <param-value>modern</param-value> </init-param> <init-param> <param-name>compilerSourceVM</param-name> <param-value>1.8</param-value> </init-param> <init-param> <param-name>compilerTargetVM</param-name> <param-value>1.8</param-value> </init-param> However, I get the following error: org.apache.jasper.JasperException: org.apache.jasper.JasperException: Unable to compile class for JSP org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:549) org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:378) 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:728) ... Caused by java.io.IOException: unexpected tag: 18 at org.apache.jasper.compiler.SmapUtil$SDEInstaller.copyConstantPool(SmapUtil.java:434) at org.apache.jasper.compiler.SmapUtil$SDEInstaller.addSDE(SmapUtil.java:251) at org.apache.jasper.compiler.SmapUtil$SDEInstaller.install(SmapUtil.java:223) at org.apache.jasper.compiler.SmapUtil$SDEInstaller.install(SmapUtil.java:200) at org.apache.jasper.compiler.SmapUtil.installSmap(SmapUtil.java:163) at org.apache.jasper.compiler.AntCompiler.generateClass(AntCompiler.java:284) at org.apache.jasper.compiler.Compiler.compile(Compiler.java:378) ... If I also add the suppressSmap parameter to the JSP servlet in conf\web.xml, the error goes away, and the JSP compiles fine: <init-param> <param-name>suppressSmap</param-name> <param-value>true</param-value> </init-param> Something about the SMAP is not playing well with Java 8 language features like the lambda expression.
Note, I realize that Java 8 is still beta. This bug may not be related to Tomcat, but could instead be a JDK issue. I have filed this bug mostly for tracking purposes, and so that someone more knowledgeable in these matters than I knows to take a look at it.
Since 1.8 isn't out yet, I wouldn't expect support for it, yet. You should be able to use the JSP precompiler to generate Java source for you and then use whatever compiler you want to actually generate .class files. But the SMAP-generation might be a tall order.
Like I said, I got the JSPs to compile in Tomcat with the Ant compiler (just without the SMAP) and I understand that Java 8 is still in flux. This bug report was so that at some point, as Java 8 becomes more solid, somebody that understands the SMAP stuff will know to figure out whether this is a JDK issue or a Tomcat issue, and fix it if it's a Tomcat issue.
This was a Java issue. I just tested this with jdk1.8.0_b81_x64 and everything works as expected. I confirmed the major version of the compiled class with javap.
Created attachment 31415 [details] Failing servlet I downloaded JDK 1.8.0 (1.8.0-b132) and Ant 1.9.3. I downloaded Tomcat 7.0.52 and set up web.xml as specified, then removed ecj-4.3.1.jar and added tools.jar from the JDK and ant.jar, ant-launcher.jar from the Ant distribution. I am able to reproduce the failure with the attached servlet. Note that compiling servlets using JDK 1.8.0 works fine as long as the servlet files don't contain any lambdas, so removing the '.filter (s -> s.length () == 5)' causes the servlet to be correctly served. Adding a lambda causes the Java 8 compiler to add an InvokeDynamic target to the constant pool and triggers the SMAP failure. http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4 The exact exception is: java.io.IOException: unexpected tag: 18 at org.apache.jasper.compiler.SmapUtil$SDEInstaller.copyConstantPool(SmapUtil.java:431) at org.apache.jasper.compiler.SmapUtil$SDEInstaller.addSDE(SmapUtil.java:248) at org.apache.jasper.compiler.SmapUtil$SDEInstaller.<init>(SmapUtil.java:220) at org.apache.jasper.compiler.SmapUtil$SDEInstaller.install(SmapUtil.java:199) at org.apache.jasper.compiler.SmapUtil.installSmap(SmapUtil.java:163) at org.apache.jasper.compiler.AntCompiler.generateClass(AntCompiler.java:284) at org.apache.jasper.compiler.Compiler.compile(Compiler.java:378) at org.apache.jasper.compiler.Compiler.compile(Compiler.java:353) at org.apache.jasper.compiler.Compiler.compile(Compiler.java:340) at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:657) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:357) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334) 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.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 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.StandardWrapperValve.invoke(StandardWrapperValve.java:220) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170) 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:315) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:744)
Looks like we have something to fix here.
Created attachment 31416 [details] Proposed patch to alleviate crash behaviour I propose the following very simple patch to stop the crashing. I suppose there is some more work to do to verify the SMAP data with Java 8 classfiles.
Fixed in 8.0.x for 8.0.5 onwards, 7.0.x for 7.0.53 onwards and 6.0.x for 6.0.40 onwards.