Mantis - Resin
Viewing Issue Advanced Details
456 minor always 11-17-05 00:00 01-27-06 14:48
urutora90  
ferg  
high  
closed 3.0.15  
3.0.15 fixed  
none    
none 3.0.18  
0000456: Error when doing xsl transformation: flush() may not be called in a body
RSN-505
The following JSP throws an exception when called:

test.jsp:
----------
<%@ page contentType="text/html" %>
<%@ taglib uri="http://java.sun.com/jstl/xml" [^] prefix="x" %>
<%@ taglib uri="http://java.sun.com/jstl/core" [^] prefix="c" %>

<c:set var="sheet"><?xml version="1.0"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> [^]
        <xsl:template match="/">
            <div>hello world</div>
        </xsl:template>
    </xsl:stylesheet>
</c:set>

<c:set var="result">
    <x:transform xslt="${sheet}" xsltSystemId="xslt">
        <foo/>
    </x:transform>
</c:set>

<c:out value="${result}"/>

----------

The stack trace I get is:

javax.servlet.ServletException: javax.servlet.jsp.JspException: javax.xml.transform.TransformerException: java.io.IOException: flush() may not be called in a body
    at com.caucho.jsp.PageContextImpl.handlePageException(PageContextImpl.java:1058)
    at _jsp._test__jsp._jspService(_test__jsp.java:68)
    at com.caucho.jsp.JavaPage.service(JavaPage.java:60)
    at com.caucho.jsp.Page.pageservice(Page.java:570)
    at com.caucho.server.dispatch.PageFilterChain.doFilter(PageFilterChain.java:159)
    at com.caucho.server.webapp.WebAppFilterChain.doFilter(WebAppFilterChain.java:178)
    at com.caucho.server.dispatch.ServletInvocation.service(ServletInvocation.java:229)
    at com.caucho.server.http.HttpRequest.handleRequest(HttpRequest.java:259)
    at com.caucho.server.port.TcpConnection.run(TcpConnection.java:386)
    at com.caucho.util.ThreadPool.runTasks(ThreadPool.java:490)
    at com.caucho.util.ThreadPool.run(ThreadPool.java:423)
    at java.lang.Thread.run(Thread.java:534)
Caused by: javax.servlet.jsp.JspException: javax.xml.transform.TransformerException: java.io.IOException: flush() may not be called in a body
    at com.caucho.jstl.rt.XmlTransformTag.doEndTag(XmlTransformTag.java:223)
    at _jsp._test__jsp._jspService(_test__jsp.java:53)
    ... 10 more
Caused by: javax.xml.transform.TransformerException: java.io.IOException: flush() may not be called in a body
    at org.apache.xalan.transformer.TransformerImpl.transformNode(TransformerImpl.java:1276)
    at org.apache.xalan.transformer.TransformerImpl.transform(TransformerImpl.java:668)
    at org.apache.xalan.transformer.TransformerImpl.transform(TransformerImpl.java:1129)
    at org.apache.xalan.transformer.TransformerImpl.transform(TransformerImpl.java:1107)
    at com.caucho.jstl.rt.XmlTransformTag.doEndTag(XmlTransformTag.java:218)
    ... 11 more
Caused by: java.io.IOException: flush() may not be called in a body
    at org.apache.xalan.serialize.SerializerToXML.flushWriter(SerializerToXML.java:1514)
    at org.apache.xalan.serialize.SerializerToXML.endDocument(SerializerToXML.java:738)
    at org.apache.xalan.transformer.ResultTreeHandler.endDocument(ResultTreeHandler.java:192)
    at org.apache.xalan.transformer.TransformerImpl.transformNode(TransformerImpl.java:1224)
    ... 15 more


The XSLT related system properties I've specified in resin.conf are:

<system-property javax.xml.parsers.DocumentBuilderFactory=
"org.apache.xerces.jaxp.DocumentBuilderFactoryImpl"/>
<system-property javax.xml.transform.TransformerFactory=
"org.apache.xalan.processor.TransformerFactoryImpl"/>
Windows XP, JDK 1.4.2_10 (issue exists also mit JDK 5 update 5), Fast-JSTL

Notes
(0000485)
urutora90   
11-17-05 00:00   
After some research, I found out that the cause is com.caucho.jsp.BodyContentImpl since flush() will always throw an IOException since 3.0.15 (this seems to be the correct behaviour according to the JspWriter API).

This bug can be circumvented by changing for example com.caucho.jstl.rt.XmlTransformTag (line 204) to:
      Result result;
      Node top = null;
      java.io.StringWriter buffer = null;
      if (_result != null) {
        result = (Result) _result;
      }
      else if (_var != null) {
        top = new com.caucho.xml.QDocument();
        
        result = new DOMResult(top);
      }
      else {
        buffer = new java.io.StringWriter();
        result = new StreamResult(buffer);
      }

      transformer.transform(source, result);

      if (_result != null) {
      } else if (_var != null)
        CoreSetTag.setValue(pageContext, _var, _scope, top);
      else {
        out.print(buffer.getBuffer().toString());
      }