Environment: Tomcat 5.5 running embedded in JBoss 4.0.3SP1 JVM: java version "1.5.0_06" JVM args: -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n -Dprogram.name=run.bat-Xms128m -Xmx512m -XX:MaxPermSize=256m When using the JDT compiler to compile JSPs on-the-fly, a very large JSP throws the following exception: java.lang.InternalError: name is too long to represent [full stack at end of bug] This seems to be related to the follow JVM bug: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6294277 but this only occurs if the JDT compiler is in use. Precompiling the same JSP from an external ANT script using (1.5) javac does not cause the problem. The ANT compiled JSP's class file is 914KB while the JDT version is 1016 KB. The original java src files are 3130 KB (52701 lines) for the ANT version and 3223 (56750 lines) for the JDT version. The number of lines of source seems to be a factor here, if I turn on the trimSpaces flag for jasper, the number of lines of in the src file drops and the JSP starts to work again. As a test, I took the .java file from the container, compiled it using javac outside the container and deployed it - it worked fine. I've posted the original JSP and both versions of the .java and .class files to: http://www.3ptsoft.com/bug/jasper-bug.zip My suspicion is that JDT is stuffing too much debug data into the class file (see above bug reference) - perhaps there is a way to control the behaviour of the JDT compiler to prevent this until Sun resolves their side of the issue? Workaround: precompile the JSPs outside of Tomcat: <target name="jspc" description="compiles JSPs" if="compile.jsps" > <!-- Precompile JSPs --> <taskdef classname="org.apache.jasper.JspC" name="jasper2" > <classpath refid="build.classpath" /> </taskdef> <jasper2 compilertargetvm="1.5" compilersourcevm="1.5" classdebuginfo="true" listErrors="true" verbose="3" validateXml="false" uriroot="${output.dir}/web" webXmlFragment="${output.dir}/web/WEB-INF/generated_web.xml" outputDir="${output.dir}/web/WEB-INF/src"> </jasper2> <!-- Insert the generated paths --> <loadfile property="web.xml" srcFile="${output.dir}/web/WEB-INF/generated_web.xml"/> <replace file="${output.dir}/web/WEB-INF/web.xml" value="${web.xml}"> <replacetoken><![CDATA[<!-- @jasper-paths@ -->]]></replacetoken> </replace> <javac source="1.5" optimize="off" destdir="${output.dir}/web/WEB-INF/classes" deprecation="${javac.deprecation}" nowarn="${compile.nowarn}" debug="${compile.debug}" debuglevel="lines,vars,source" compiler="${javac.compiler}" executable="${javac.path}"> <src path="${output.dir}/web/WEB-INF/src" /> <classpath refid="build.classpath" /> </javac> </target> stack trace thrown: 12:51:49,296 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/TestAdmin].[jsp]] - Servlet.service() for servlet jsp threw exception java.lang.InternalError: name is too long to represent at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:620) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124) at java.net.URLClassLoader.defineClass(URLClassLoader.java:260) at java.net.URLClassLoader.access$100(URLClassLoader.java:56) at java.net.URLClassLoader$1.run(URLClassLoader.java:195) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:188) at org.apache.jasper.servlet.JasperLoader.loadClass(JasperLoader.java:158) at org.apache.jasper.servlet.JasperLoader.loadClass(JasperLoader.java:71) at org.apache.jasper.JspCompilationContext.load(JspCompilationContext.java:589) at org.apache.jasper.servlet.JspServletWrapper.getServlet(JspServletWrapper.java:137) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:305) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:264) at javax.servlet.http.HttpServlet.service(HttpServlet.java:810) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:672) at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:463) at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:398) at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:301) at org.apache.myfaces.context.servlet.ServletExternalContextImpl.dispatch(ServletExternalContextImpl.java:416) at org.apache.myfaces.application.jsp.JspViewHandlerImpl.renderView(JspViewHandlerImpl.java:234) at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:372) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:138) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at com.tps.framework.servlet.NDCFilter.doFilter(NDCFilter.java:58) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at com.tps.framework.servlet.HibernateFilter.doFilter(HibernateFilter.java:48) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at com.tps.framework.servlet.HivemindFilter.doFilter(HivemindFilter.java:55) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.apache.myfaces.component.html.util.ExtensionsFilter.doFilter(ExtensionsFilter.java:124) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:81) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178) at org.jboss.web.tomcat.security.CustomPrincipalValve.invoke(CustomPrincipalValve.java:39) at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:159) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:59) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:744) at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527) at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112) at java.lang.Thread.run(Thread.java:595)
First, note that Tomcat already supports the classdebuginfo (true by default, can be set to false) option to be passed into the compiler at runtime: maybe try using that? (See http://tomcat.apache.org/tomcat-5.5-doc/jasper-howto.html#Configuration for documentation) Second, as you noted, this is a combination of a JDK and/or Eclipse JDT bugs, not a Tomcat bug per-se. I hesitate to put in place any temporary workaround as a band-aid, and then remove it later when the vendor has fixed their root problem. Instead, you may want to bring this up in the relevant Eclipse forum and/or bug tracking system. Thanks.
The specific JVM bug that is occuring is already noted at Sun (anyone reading this, please vote for Sun to fix the bug - http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6294277). I've also posted a bug to Eclipse's bugzilla: https://bugs.eclipse.org/bugs/show_bug.cgi?id=136752 I would suggest adding some information to Tomcat's docs because Tomcat's default configuration is to use debug mode and the JDT compiler. The bug will occur without the end-user being aware that the root cause is the use of JDT and the error from the JVM is very cryptic. The only resolution is either to find this bug or hunt-and-peck through the config settings to fix. Also, I'm not a JDT expert, but it might be worthwhile looking into if the extra debug information being included by JDT can be turned off by Tomcat on compilation. From what I understand, the field in question is not for use by java-debuggers but for non-java compilers.
I'm reopening this because it looks like JDT does not put in a SourceDebugExtension during compilation. Looking at the Jasper source code, there are references to the SourceDebugExtension and JSR-045 in the SmapUtils.class. I'm not sure how this is used or under what circumstances. I am going to try rerunning the test cases today using javac inside the container instead of jdt. I will post the results here and the the Eclipse bug as well. The SmapUtils.class can be seen here: http://svn.apache.org/viewcvs.cgi/tomcat/jasper/tc5.5.x/src/share/org/apache/jasper/compiler/SmapUtil.java?view=markup The JDT bug I opened can be found here: https://bugs.eclipse.org/bugs/show_bug.cgi?id=136752
If you want a change to Tomcat's docs, please let us know what text you'd like us to use, and we'll gladly add it to the docs. But please don't reopen just for the sake of reopening it, because it's a JDT and/or Sun bug, not a Tomcat bug, as already noted above.
(In reply to comment #4) I didn't reopen this for the sake of re-opening it nor for the documentation fix... JDT *does not* add the JSR-045 SourceDebugExtension - Jasper seems to. Please see comment #3 that I added when I reopened this bug - the SourceDebugExtension code is in Tomcat's SVN repository (see the link in #4). The Sun JVM issue is really a spec documentation conflict. The overall JVM specs quite clearly says there is a 4K limit for attributes, the JSR spec says something different. I would think the JVM spec is much more important here. For large JSPs, Jasper is adding > 4K work of SourceDebugExtension information to the compiled classes - this violates the JVM spec and causes the bug. As I said in my comment, I don't know how the SmapUtil and related classes are being used by Jasper or when they are used. According to the analysis from the JDT developer looking at this issue on their end: "In the .class file that I got, there is such an attribute at the end. Attribute: SourceDebugExtension Length: 81342." Since JDT does not add the SourceDebugExtension attribute during compilation, it would appear that Jasper is adding it to the bytecode after compilation? I'm open to an alternate explanation... I'm attaching the .class and .java files to this bug so you can look at them too. In my opinion, this should be re-opened and looked into, but I will defer to you.
Created attachment 18132 [details] Large JSP compiled by jdt here's the file that was sent to the JDT for analysis. As they logged in their Bugzilla, JDT doesn't add the attribute in question during compilation but you can see it in the .class file at the end.
OK, now I understand why you re-opened it. Thanks for the explanation. I'll look into it when I get a chance, hopefully someone else will get a chance sooner ;)
(In reply to comment #5) > The Sun JVM issue is really a spec documentation conflict. The overall JVM specs > quite clearly says there is a 4K limit for attributes, the JSR spec says > something different. I would think the JVM spec is much more important here. > > For large JSPs, Jasper is adding > 4K work of SourceDebugExtension information > to the compiled classes - this violates the JVM spec and causes the bug. Erik, Where did you get that information about the 4K limit. An attribute length can be on 4 unsigned byte.
I have added a known issues section to the Jasper/JSP how-to that explains this issue and gives some options on how to work around it.