Bug 54475 - SMAP broken in Java 8 for JSP compile
Summary: SMAP broken in Java 8 for JSP compile
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 8
Classification: Unclassified
Component: Jasper (show other bugs)
Version: 8.0.x-trunk
Hardware: All All
: P2 major (vote)
Target Milestone: ----
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-01-23 18:21 UTC by Nick Williams
Modified: 2014-03-23 09:39 UTC (History)
1 user (show)



Attachments
Failing servlet (283 bytes, text/plain)
2014-03-20 10:19 UTC, Robbie Gibson
Details
Proposed patch to alleviate crash behaviour (1.13 KB, patch)
2014-03-20 13:09 UTC, Robbie Gibson
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Nick Williams 2013-01-23 18:21:08 UTC
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.
Comment 1 Nick Williams 2013-01-23 18:29:00 UTC
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.
Comment 2 Christopher Schultz 2013-01-23 18:38:01 UTC
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.
Comment 3 Nick Williams 2013-01-23 19:36:05 UTC
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.
Comment 4 Mark Thomas 2013-03-21 23:03:14 UTC
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.
Comment 5 Robbie Gibson 2014-03-20 10:19:24 UTC
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)
Comment 6 Mark Thomas 2014-03-20 12:14:24 UTC
Looks like we have something to fix here.
Comment 7 Robbie Gibson 2014-03-20 13:09:02 UTC
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.
Comment 8 Mark Thomas 2014-03-23 09:39:48 UTC
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.