Reputation: 494
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
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 thepage
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 thepageEncoding
andcontentType
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