You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Nasry Al-Haddad <al...@gmail.com> on 2014/10/21 17:26:31 UTC

Tomcat 7.0: Unused primitive long or double variables prevent Tomcat from compiling JSP

Hello,

Have an issue on Tomcat 7.0.55 on Windows XP, where Tomcat refuses to
compile a JSP if a primitive variable of type "long" or "double" references
a session attribute, but the variable is never used. Below are three
scenarios for type "long". The issue can be regenerated on a fresh extract
of Tomcat 7.0.55 archive.

Tomcat version: 7.0.55

Java version: jdk1.7.0_67

OS: WinXP


Note-1: The issue applies for "long" and "double"; but NOT for "int" and
"float".

Note-2: The issue does not persist if the variables, though primitive and
never used, are assigned to literals, as in (long v1 = 1L;)


First Scenario (works):

- Both variables are of "primitive" type long

- Both variables are used

- Tomcat generates both JAVA and CLASS files of JSP

- No exceptions are raised on requests.

session.setAttribute("v1", 1L);

session.setAttribute("v2", 2L);

long v1 = (Long) session.getAttribute("v1");

long v2 = (Long) session.getAttribute("v2");          //<-- Primitive

out.write(String.valueOf(v1));

out.write(String.valueOf(v2));


Second Scenario (does not work):

- Both variables are of "primitive" type long

- One variable is used, "the other is not used"

- Tomcat generates JAVA file, "but not the CLASS file"

- An exception is raised (see at the end)

session.setAttribute("v1", 1L);

session.setAttribute("v2", 2L);

long v1 = (Long) session.getAttribute("v1");

long v2 = (Long) session.getAttribute("v2");          //<-- Primitive

out.write(String.valueOf(v1));

*//*out.write(String.valueOf(v2)); //<-- commented


Third Scenario (works):

- Both variables are of type long, "using Wrapper class"

- Don't care if any of the variables is used or not

- Tomcat generates both JAVA and CLASS files of JSP

- No exceptions are raised

session.setAttribute("v1", 1L);

session.setAttribute("v2", 2L);

Long v1 = (Long) session.getAttribute("v1");

Long v2 = (Long) session.getAttribute("v2"); //<-- Wrapper

out.write(String.valueOf(v1));

//out.write(String.valueOf(v2)); //<-- commented


To try the above tests, just extract tomcat's archive (*as-is*) and add a
simple webapp with one JSP file containing one of the scenarios listed
below, and try to access the JSP page.


As for the raised exception:

Oct 21, 2014 4:57:48 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [jsp] in context with path [/test]
threw exception [org.apache.jasper.JasperException: Unable to compile class
for JSP] with root cause
java.lang.ArrayIndexOutOfBoundsException: -1
at
org.eclipse.jdt.internal.compiler.codegen.StackMapFrame.addStackItem(StackMapFrame.java:92)
at org.eclipse.jdt.internal.compiler.ClassFile.traverse(ClassFile.java:5544)
at
org.eclipse.jdt.internal.compiler.ClassFile.generateStackMapTableAttribute(ClassFile.java:4303)
at
org.eclipse.jdt.internal.compiler.ClassFile.completeCodeAttribute(ClassFile.java:1378)
at
org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration.generateCode(AbstractMethodDeclaration.java:338)
at
org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration.generateCode(AbstractMethodDeclaration.java:270)
at
org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.generateCode(TypeDeclaration.java:566)
at
org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.generateCode(TypeDeclaration.java:635)
at
org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration.generateCode(CompilationUnitDeclaration.java:368)
at org.eclipse.jdt.internal.compiler.Compiler.process(Compiler.java:781)
at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:470)
at
org.apache.jasper.compiler.JDTCompiler.generateClass(JDTCompiler.java:466)
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:171)
at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
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:1070)
at
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
at
org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2440)
at
org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2429)
at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)

Best Regards,

Nasry Al-Haddad

Re: Tomcat 7.0: Unused primitive long or double variables prevent Tomcat from compiling JSP

Posted by Konstantin Kolinko <kn...@gmail.com>.
2014-10-21 19:26 GMT+04:00 Nasry Al-Haddad <al...@gmail.com>:
> Hello,
>
> Have an issue on Tomcat 7.0.55 on Windows XP, where Tomcat refuses to
> compile a JSP if a primitive variable of type "long" or "double" references
> a session attribute, but the variable is never used. Below are three
> scenarios for type "long". The issue can be regenerated on a fresh extract
> of Tomcat 7.0.55 archive.
>
> Tomcat version: 7.0.55
>
> Java version: jdk1.7.0_67
>
> OS: WinXP
>
>
> Note-1: The issue applies for "long" and "double"; but NOT for "int" and
> "float".
>
> Note-2: The issue does not persist if the variables, though primitive and
> never used, are assigned to literals, as in (long v1 = 1L;)
>
>
> First Scenario (works):
>
> - Both variables are of "primitive" type long
>
> - Both variables are used
>
> - Tomcat generates both JAVA and CLASS files of JSP
>
> - No exceptions are raised on requests.
>
> session.setAttribute("v1", 1L);
>
> session.setAttribute("v2", 2L);
>
> long v1 = (Long) session.getAttribute("v1");
>
> long v2 = (Long) session.getAttribute("v2");          //<-- Primitive
>
> out.write(String.valueOf(v1));
>
> out.write(String.valueOf(v2));
>
>
> Second Scenario (does not work):
>
> - Both variables are of "primitive" type long
>
> - One variable is used, "the other is not used"
>
> - Tomcat generates JAVA file, "but not the CLASS file"
>
> - An exception is raised (see at the end)
>
> session.setAttribute("v1", 1L);
>
> session.setAttribute("v2", 2L);
>
> long v1 = (Long) session.getAttribute("v1");
>
> long v2 = (Long) session.getAttribute("v2");          //<-- Primitive
>
> out.write(String.valueOf(v1));
>
> *//*out.write(String.valueOf(v2)); //<-- commented
>
>
> Third Scenario (works):
>
> - Both variables are of type long, "using Wrapper class"
>
> - Don't care if any of the variables is used or not
>
> - Tomcat generates both JAVA and CLASS files of JSP
>
> - No exceptions are raised
>
> session.setAttribute("v1", 1L);
>
> session.setAttribute("v2", 2L);
>
> Long v1 = (Long) session.getAttribute("v1");
>
> Long v2 = (Long) session.getAttribute("v2"); //<-- Wrapper
>
> out.write(String.valueOf(v1));
>
> //out.write(String.valueOf(v2)); //<-- commented
>
>
> To try the above tests, just extract tomcat's archive (*as-is*) and add a
> simple webapp with one JSP file containing one of the scenarios listed
> below, and try to access the JSP page.
>
>
> As for the raised exception:
>
> Oct 21, 2014 4:57:48 PM org.apache.catalina.core.StandardWrapperValve invoke
> SEVERE: Servlet.service() for servlet [jsp] in context with path [/test]
> threw exception [org.apache.jasper.JasperException: Unable to compile class
> for JSP] with root cause
> java.lang.ArrayIndexOutOfBoundsException: -1
> at
> org.eclipse.jdt.internal.compiler.codegen.StackMapFrame.addStackItem(StackMapFrame.java:92)
> at org.eclipse.jdt.internal.compiler.ClassFile.traverse(ClassFile.java:5544)
> at
> org.eclipse.jdt.internal.compiler.ClassFile.generateStackMapTableAttribute(ClassFile.java:4303)
> at
> org.eclipse.jdt.internal.compiler.ClassFile.completeCodeAttribute(ClassFile.java:1378)
> at
> org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration.generateCode(AbstractMethodDeclaration.java:338)
> at
> org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration.generateCode(AbstractMethodDeclaration.java:270)
> at
> org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.generateCode(TypeDeclaration.java:566)
> at
> org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.generateCode(TypeDeclaration.java:635)
> at
> org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration.generateCode(CompilationUnitDeclaration.java:368)
> at org.eclipse.jdt.internal.compiler.Compiler.process(Compiler.java:781)
> at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:470)
> at
> org.apache.jasper.compiler.JDTCompiler.generateClass(JDTCompiler.java:466)
> 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:171)
> at
> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
> 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:1070)
> at
> org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
> at
> org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2440)
> at
> org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2429)
> at
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
> at
> org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
> at java.lang.Thread.run(Thread.java:745)
>
> Best Regards,
>
> Nasry Al-Haddad

Hi!

Thank you for detailed report. I was able to reproduce the issue.

The crash happens not in our code, but in Eclipse Java compiler (ECJ),
that Tomcat calls to compile the page.

It is possible to replace the version of ecj.jar in Tomcat with a
later one, but unfortunately, this issue is reproducible with the next
available version (ecj-4.4.1) as well as with current nightly build of
the compiler.

I reported the issue to the Eclipse project:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=448112


Best regards,
Konstantin Kolinko

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org