gcpdev-guy
gcpdev-guy

Reputation: 494

java.io.IOException: Stream closed in Struts 2.5.26 and Tiles 3.0.0

After migrating the application to Struts 2 and Tiles 3.0.0, one of the pages throwing the following exception

SEVERE: Servlet.service() for servlet jsp threw exception java.io.IOException: Stream closed at org.apache.jasper.runtime.JspWriterImpl.ensureOpen(JspWriterImpl.java:210) at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:115) at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:194) at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:126) at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:80) at org.apache.jsp.pages.common.baseLayout_jsp._jspService(baseLayout_jsp.java:178) at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432) 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.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:

When I looked at source code for baseLayout_jsp.java I see the following line which throws that exception

    finally {
          _jspxFactory.releasePageContext(_jspx_page_context);
        }

but the baseLayout.jsp only has html and tiles codes

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <%@ taglib uri="/WEB-INF/struts-tags.tld" prefix="s"%>
    <%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
    <s:property value="getText('label.version')"/>
    
    <html>
    <HEAD>
    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />
    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
        pageEncoding="ISO-8859-1"%>
    <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <META name="GENERATOR" content="IBM Software Development Platform">
    
    <TITLE><tiles:getAsString name="title" ignore="true"/></TITLE>
    
        <link href="<s:url value='/css/styles.css'/>" type=text/css rel=styleSheet>
        <link href="<s:url value='/css/sor_styles.css'/>" type=text/css rel=styleSheet>
        <link href="<s:url value='/css/ucd_styles.css'/>" type=text/css rel=styleSheet>
        
        <script language="JavaScript" src="<s:url value='/js/common/app.js'/>"></script>
        <script language="JavaScript" src="<s:url value='/js/common/validations.js'/>"></script>
    </HEAD>
    
    <BODY>
    <TABLE  border="0" cellpadding="0" cellspacing="0" height="100%" width="100%">
        <TBODY>
            <TR>
                <TD height="66" colspan="2"><tiles:insertAttribute name="header" /><s:debug value="PAGE TESTING"/></TD>
            </TR>
            <TR>
    
                <TD width="100%" height="100%" valign="top">
                    <div id="mainBody">
                        <tiles:insertAttribute name="tabs" />
                        <tiles:insertAttribute name="here" />
                        <tiles:insertAttribute name="error_response" /> 
                        <tiles:insertAttribute name="body" />
                    </div>
                </TD>
            </TR>
        <TR>
        <TD colspan="2"><tiles:insertAttribute name="footer" /></TD>
        </TR>
        </TBODY>
    </TABLE>
    </BODY>
    </html>

Any idea why I am seeing this exception? I searched it out there but examples shows that most of the pages were using Stream writers when they get this exception but not in my case.

Upvotes: 1

Views: 1547

Answers (1)

Illya Kysil
Illya Kysil

Reputation: 1756

Summary:

The page directive in the provided example is located quite far from the beginning of the JSP file which may trigger the commit of the response which then leads to the failure while trying to set the Content-Type header of the response.

Make the page directive with the contentType and pageEncoding attributes the very first line of your JSP file.

<%@ page contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ taglib uri="/WEB-INF/struts-tags.tld" prefix="s"%>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
<s:property value="getText('label.version')"/>

<!-- rest of the page -->
...

References:

Apache Tomcat 7 supports JSP Specification 2.2 as per The mapping between the specifications and the respective Apache Tomcat versions.

According to the JSP Specification 2.2, section JSP.1.10.1 The page Directive (emphasis is mine):

A translation unit (JSP source file and any files included via the include directive) can contain more than one instance of the page directive, all the attributes will apply to the complete translation unit (i.e. page directives are position independent). An exception to this position independence is the use of the pageEncoding and contentType attributes in the determination of the page character encoding; for this purpose, they should appear at the beginning of the page (see Section JSP.4.1).

Same statement is present in the Jakarta Server Pages 3.0 Specification.

Upvotes: 2

Related Questions