_jspService超过了65535字节的限制。

36

我正在处理运行在Websphere 7 (JDK 6)上的旧版servlet代码。开发环境使用Tomcat 6 (JDK 6)。

  1. 为什么它在Websphere 7上工作而在Tomcat 6上不工作?
  2. 这是否与应用服务器有关?

如果您对问题2的答案是肯定的,除了分解代码或使用动态包含,您是否有Tomcat 6 (JDK 6)的解决方法?

时间表不允许将静态包含更改为动态包含,主要原因是大多数页面都与业务模型代码耦合,包括应用程序的主模板。


正在下载WAS 6 Express。 - setzamora
也许下一个问题是,是否可以更改JVM的方法大小限制? - setzamora
1
我会重构(大)部分代码以包含标签。有缺陷的商业模式不是一个论点。 - BalusC
“下一个问题”的答案是,不行。很简单。限制在于类文件的格式…而不是JVM。 - Stephen C
请参见此链接:https://dev59.com/L1vUa4cB1Zd3GeqPt3pt#26647081。 - NoNaMe
11个回答

24

我已经没有能够转化为 jsp:include 的静态html/jss/css块了(大部分都是非静态html)...

你可以在web.xml文件中设置mappedfile为false,这样就可以摆脱许多并不一定适合放入 include的静态行,但它们却可以累计节省空间:

<servlet>
    <servlet-name>jsp</servlet-name>
    <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
    ...
    <init-param>
        <param-name>mappedfile</param-name>
        <param-value>false</param-value>
    </init-param>
    ...
</servlet>

Peter Hart的<c:catch>解决方案听起来也是一个不错的选择。


谢谢,这个解决方案帮了我很多,节省了我的时间。 - mahi

23

看起来你遇到了一个64k方法限制的问题,可能是由Tomcat将你的JSP构建成类的方式导致的。这个页面建议像这样更改你的静态包含内容:

<%@ include file="test.jsp" %>
为了避免这个问题,可以使用动态包含,如下所示:
<jsp:include page="test.jsp" /> 

是的,我知道这个问题,我已经重新表达了我的上一个问题,那就是动态包含。 - setzamora
啊,我怀疑你在Tomcat上没有太多选择,除非你想对其进行修改以分解长方法以避免限制。无法保证Web容器如何将你的JSP分解为要编译成类的Java代码。你需要找到一个与Tomcat不同的容器,也许可以尝试Jetty或Resin? - WhiteFang34
对我来说也是一样的。谢谢! - migueloop
不错,但如果我使用jsp:include包含它,那么<form:这个标签对我来说就无法工作。如果有任何替代方法,请帮助我。 - Srikanth
现在理解了,taglib 在父页面中,所以 <form: tag 不起作用。现在我已经将 taglib 添加到子页面中,可以正常工作了。谢谢。 - Srikanth

14

最好直接参考以下链接所述的位置进行更改: https://www.assetbank.co.uk/support/documentation/knowledge-base/byte-limit-exceeded-error/

定位文件[Tomcat_Home]/conf/web.xml,并搜索文件中的'JspServlet'。这将返回一个包含一些<init-param>值的xml节点<servlet>。您需要添加一个与下面相同的额外<init-param>

<init-param>
    <param-name>mappedfile</param-name>
    <param-value>false</param-value>
</init-param> 

对于Tomcat用户来说,这更清晰、更直接。

其他参考解决方案,在这里集中阅读(大部分已经在之前的评论中提到),链接为:http://answered.site/development-environment-setup-uses-tomcat-6-jdk-6-why-does-it-work/603017/

这个问题也存在于Tomcat-8和JDK1.8(Java 8)中。


...但是 answered.site 的链接没有。 - FreeText
1
是的,其他网站无法工作,但仍然可以在https://support.assetbank.co.uk/hc/en-gb/articles/115005208888-How-do-I-fix-a-65535-bytes-limit-Stacktrace-中查看。 - Osify
谢谢您提供的提示和链接,它们确实有所帮助。不过很遗憾,在我的情况下只减少了生成的Java/class文件大小的2%。 - leole

4
在standalone.xml中,为JBoss EAP 6添加以下代码,放置在web子系统下面。
<configuration>
    <jsp-configuration development="true" mapped-file="false"/>
</configuration>

它解决了我的问题。

4
有时将JSP拆分为包含文件可能没有意义或不起作用。另一种在编译时将JSP分解为单独方法的方法是使用将JSP分成多个段落。

您介意详细说明如何通过<c:catch>强制更多的片段吗?我找不到任何其他关于这个“hack”的来源,我现在非常需要使用它!感谢您的帮助! - Benjamin Seiller
没关系 - 找到了一个“更简洁”的解决方案(jsp:include),有时候阅读能力真的很重要 :) - Benjamin Seiller
1
要使用includes,您必须创建更多的文件。通常这没问题。但是当不行时,将页面中的代码分成用<c:catch>包装的块。这会强制生成的servlet将页面分成多个方法。 - Peter J. Hart

3
因为它们有不同的JSP编译器,将JSP转换为不同的Java代码。Tomcat JSP编译器(Jasper)显然无法处理大型JSP。
不。这些限制已经硬编码到类文件的格式/结构中。
详细信息请参见{{link1:JVM规范}}...但它相当复杂,并且从您的问题中并不完全清楚哪个限制受到了限制。(但这是无关紧要的...它们不能被更改。)

这实际上并不简单。method_count字段限制每个类的方法数量,而不是每个方法的代码长度。Code_attribute结构中的相关字段code_length是一个32位无符号整数,但由于其他属性使用16位无符号整数索引代码,因此在类文件格式规范中还指出“code_length项的值必须小于65536”。在某些情况下,它甚至必须小于65535,因为索引65535上的指令不能受到异常处理程序的保护。 - jarnbjo
命中错误与方法名“_jspService”有关,这是jsp代码转换成的内容。编译器无法将长代码拆分为多个(链接)“_jspServiceXXX”方法。方法的字节码长度不能超过65535字节。一些其他工具也无法生成正确的代码。例如,“asm”在生成大型类的“字节码”时也会失败,并且错误是相同的。 - bestsss

2

今天我遇到了这个问题
当我使用Tomcat 8.0.30而不是Tomcat 8.0.39时,我的问题得到了解决


1
太神奇了,这真的帮助了我(必须运行旧项目以修复某些问题)。我最初使用的是apache-tomcat-7.0.78,但出现了上述异常。然后我尝试了apache-tomcat-8.0.46,但仍然出现异常。最后我尝试了Apache存档中的apache-tomcat-8.0.30,它真的起作用了。 我不会依赖它进行生产,但可以快速启动bugfix会话。完美。谢谢。 - stefitz

2
通过将初始化参数“mappedFile”设置为“false”,我成功解决了问题。但是使用Eclipse插件时,有时它会被删除,需要重新在Tomcat主目录中设置该参数。

2

如果您要在使用嵌入式Tomcat的Spring Boot时修复_jspService超出65535字节限制的错误,则可以在application.properties中使用以下配置:

server.servlet.jsp.init-parameters.mappedfile=false

1

编辑:给出的解决方案并不是真正的解决方案,而是误解(问题无法在所有Tomcat版本上重现),很抱歉。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接