Bug 22892

Summary: Problem with fmt:formatDate tag on large pages (in 1.0.3 actually)
Product: Taglibs Reporter: Chris Mein (RBOS) <Christopher.MEIN>
Component: Standard TaglibAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED INVALID    
Severity: normal    
Priority: P3    
Version: 1.0.2   
Target Milestone: ---   
Hardware: PC   
OS: All   

Description Chris Mein (RBOS) 2003-09-02 17:18:05 UTC
This error actually happens in 1.0.3

On any page that produces more data than the current JSP buffer size and 
includes the formatDate tag the following error is produced (running under 
OC4J):

java.lang.IllegalStateException: Response is already committed!
	at com.evermind[Oracle9iAS (9.0.3.0.0) Containers for 
J2EE].server.http.EvermindHttpServletResponse.setLocale
(EvermindHttpServletResponse.java:1754)
	at 
org.apache.taglibs.standard.tag.common.fmt.SetLocaleSupport.setResponseLocale
(SetLocaleSupport.java:234)
	at 
org.apache.taglibs.standard.tag.common.fmt.SetLocaleSupport.getFormattingLocale
(SetLocaleSupport.java:320)
	at org.apache.taglibs.standard.tag.common.fmt.FormatDateSupport.doEndTag
(FormatDateSupport.java:148)
	at _csrrefactored._editApprover._jspService(_editApprover.java:1281)
	[SRC:/csrRefactored/editApprover.jsp:280]

This problem can be removed by setting the page buffer higher (above the size 
of the page) like

<%@ page buffer="512k"  %>

Looking at the source code where the exception occurs the following method is 
called (in org.apache.taglibs.standard.tag.common.fmt.SetLocaleSupport.java)

static void setResponseLocale(PageContext pc, Locale locale) {
	// set response locale
	ServletResponse response = pc.getResponse();
	response.setLocale(locale);
	
	// get response character encoding and store it in session attribute
	if (pc.getSession() != null) {
	    pc.setAttribute(RequestEncodingSupport.REQUEST_CHAR_SET,
			    response.getCharacterEncoding(),
			    PageContext.SESSION_SCOPE);
	}
    }

After reading the Servlet specification and documentation (and in particular 
the Javadoc for ServletResponse.setLocale()) it appears that the setLocale 
method should be called before a call to getWriter().

It appears that the way this tag is written there is no way to ensure that this 
will occur. Also the setLocale call can be made many times on the page (once 
for each formatDate tag). Should this info be set into the response at all?

Note that this error cannot be reproduced on Jetty or Tomcat (I assume as they 
are more relaxed about the spec in this instance). In any case though we are 
not sure the setLocale call should be made at all.

Any feedback about this issue will be great.
Comment 1 Pierre Delisle 2003-09-10 17:50:20 UTC
The behavior of the formatting tags is in accordance with the
JSTL spec. 

With respect to the following exception:
"java.lang.IllegalStateException: Response is already committed!"

the spec clearly states in section 8.4 that:

"This assumes that the response is buffered with a big enough buffer size, since
ServletResponse.setLocale() and ServletResponse.setContentType()
must be called before ServletResponse.getWriter() in order for the specified
locale or charset to affect the construction of the writer.(1)
(1). It also assumes that the JSP container doesn't call getWriter() until it's 
about to flush the buffer. An errata has been published for the JSP 1.2
specification 
to clarify this."

As you mentioned, you have to make sure that you have a big enough
buffer, as well as verify that your container vendor complies with 
this errata of the JSP spec.

Finally, the language regarding this whole issue as been clarified 
in JSTL 1.1 as follows:

Summary:
Response Encoding
The way formatting actions influence the encoding of the response has been
clarified in sections 8.4 and 8.10. Repeated calls to
ServletResponse.setLocale() will affect the character encoding of the
response only if it has not already been set explicitely.

Please check the JSTL 1.1 spec for more details
(http://java/sun/com/jstl)