Mantis Bugtracker
  

Viewing Issue Simple Details Jump to Notes ] View Advanced ] Issue History ] Print ]
ID Category Severity Reproducibility Date Submitted Last Update
0002378 [Resin] major always 01-29-08 07:02 02-07-08 13:18
Reporter wimsie View Status public  
Assigned To ferg
Priority normal Resolution fixed  
Status closed   Product Version 3.1.3
Summary 0002378: Java files generated from JSP contains eval code in _jspService method
Description I'm using custom tags within my JSP application.
Under several conditions the overriding of doEndTag() causes unexpected
errors in Resins generated Java files of the JSPs. This is frustrating me,
because I thought the implementation of custom tags should not effect the
jspCompile process.

Here's an example of what I'm doing.
The full test project is added as war file.

I have the following 2 tag classes:

FirstTag.java

package org.example;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.*;

public class FirstTag extends BodyTagSupport {

    private static final long serialVersionUID = 3453137860578845349L;
    protected BodyContent bodyOut;

    public int doEndTag() throws JspException {
        return BodyTag.EVAL_PAGE;
    }

    public int doStartTag() throws JspException {
        // do something
        return BodyTag.EVAL_BODY_BUFFERED;
    }

    public void doInitBody() throws JspException {
        /* empty */
    }

    public int doAfterBody() throws JspException {
        if (bodyOut != null) {
            try{
                bodyOut.writeOut(bodyOut.getEnclosingWriter());
                bodyOut.clearBody();
            }catch(IOException ex){
                throw new JspException(ex.toString());
            }
        }
        return BodyTag.SKIP_BODY;
    }

    public void release() {
        bodyOut = null;
        pageContext = null;
    }
    
    public void setBodyContent(BodyContent bodycontent) {
        bodyOut = bodycontent;
    }
}

SecondTag.java

package org.example;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTag;

public class SecondTag extends FirstTag {

    private static final long serialVersionUID = -3175774083070240581L;
    private boolean redirect;

    public int doEndTag() throws JspException {
        if (redirect) {
            return BodyTag.SKIP_PAGE;
        } else {
            return super.doEndTag();
        }
    }
}

Here's the jsp I use for this example:

Resin.html

<!DOCTYPE html public "-//W3C//DTD HTML 4.0 Transitional//EN">
<%@ page language="java" %>
<%@ taglib prefix="custom" uri="http://example.org/custom" [^] %>
<html>
<head>
    <title>Resin Test Page</title>
</head>
<body>
<custom:SecondTag>
do something...

</custom:SecondTag>
expected output
</body>
</html>

This causes the following page as result:

<!DOCTYPE html public "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
    <title>Resin Test Page</title>
</head>
<body>
do something...



And here's the problem. The page stopped on call of doEndTag() of
</custom:SecondTag>.
That's the affecting source of the generated Java file. As you can see,
the problem is in _jspService method:

_Resin__html.java

/*
 * JSP generated by Resin-3.1.4 (built Tue, 04 Dec 2007 05:30:53 PST)
 */

package _jsp;
import javax.servlet.*;
import javax.servlet.jsp.*;
import javax.servlet.http.*;

public class _Resin__html extends com.caucho.jsp.JavaPage
{
  private static final java.util.HashMap<String,java.lang.reflect.Method> _jsp_functionMap = new java.util.HashMap<String,java.lang.reflect.Method>();
  private boolean _caucho_isDead;
  
  public void
  _jspService(javax.servlet.http.HttpServletRequest request,
              javax.servlet.http.HttpServletResponse response)
    throws java.io.IOException, javax.servlet.ServletException
  {
    javax.servlet.http.HttpSession session = request.getSession(true);
    com.caucho.server.webapp.WebApp _jsp_application = _caucho_getApplication();
    javax.servlet.ServletContext application = _jsp_application;
    com.caucho.jsp.PageContextImpl pageContext = com.caucho.jsp.QJspFactory.allocatePageContext(this, _jsp_application, request, response, null, session, 8192, true, false);
    javax.servlet.jsp.JspWriter out = pageContext.getOut();
    final javax.el.ELContext _jsp_env = pageContext.getELContext();
    javax.servlet.ServletConfig config = getServletConfig();
    javax.servlet.Servlet page = this;
    response.setContentType("text/html");
    org.example.SecondTag _jsp_SecondTag_0 = null;
    try {
      out.write(_jsp_string0, 0, _jsp_string0.length);
      com.caucho.jsp.BodyContentImpl _jsp_endTagHack0 = null;
      if (_jsp_SecondTag_0 == null) {
        _jsp_SecondTag_0 = new org.example.SecondTag();
        _jsp_SecondTag_0.setPageContext(pageContext);
        _jsp_SecondTag_0.setParent((javax.servlet.jsp.tagext.Tag) null);
      }

      out = pageContext.pushBody();
      _jsp_endTagHack0 = (com.caucho.jsp.BodyContentImpl) out;
      _jsp_SecondTag_0.setBodyContent(_jsp_endTagHack0);
      out.write(_jsp_string1, 0, _jsp_string1.length);
      _jsp_SecondTag_0.doAfterBody();
      out = pageContext.popBody();
      _jsp_SecondTag_0.doEndTag();
      pageContext.releaseBody(_jsp_endTagHack0);
      
<<< eval code start>>>
      if (true)
        return;
<<< eval code end>>>
        
      out.write(_jsp_string2, 0, _jsp_string2.length);
    } catch (java.lang.Throwable _jsp_e) {
      pageContext.handlePageException(_jsp_e);
    } finally {
      if (_jsp_SecondTag_0 != null)
        _jsp_SecondTag_0.release();
      com.caucho.jsp.QJspFactory.freePageContext(pageContext);
    }
  }
  .
  .
  .
  private final static char []_jsp_string2;
  private final static char []_jsp_string0;
  private final static char []_jsp_string1;
  static {
    _jsp_string2 = "\nexpected output\n</body>\n</html>\n".toCharArray();
    _jsp_string0 = "<!DOCTYPE html public \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n\n\n<html>\n<head>\n <title>Resin Test Page</title>\n</head>\n<body>\n".toCharArray();
    _jsp_string1 = "\ndo something...
\n".toCharArray();
  }
}

I've modified doEndTag() in SecondTag.java to the following:

public int doEndTag() throws JspException {
    int ret = super.doEndTag();
    if (redirect) {
        return BodyTag.SKIP_PAGE;
    } else {
        return ret;
    }
}

This doesn't work as well.
Only using the following was succesful:

public int doEndTag() throws JspException {
    if (redirect) {
        return BodyTag.SKIP_PAGE;
    } else {
        return BodyTag.EVAL_PAGE;
    }
}

instead of
if (true) {
    return;
}

the generated Java source now looks like this:

if (_jsp_end_3 == javax.servlet.jsp.tagext.Tag.SKIP_PAGE)
    return;

So, why isn't it possible to call super.doEndTag()?

I tried both Resin 3.1.3 and Resin 3.1.4 but it was still the same. The application worked fine on Resin 2.1.17.
It's the Open Source Resin installed on a SuSE Linux 10.1 system.
Additional Information
Attached Files  custom.war [^] (5,523 bytes) 01-29-08 07:02

- Relationships

- Notes
(0002733)
ferg
02-07-08 13:18

jsp/18q1
 

- Issue History
Date Modified Username Field Change
01-29-08 07:02 wimsie New Issue
01-29-08 07:02 wimsie File Added: custom.war
02-07-08 13:18 ferg Note Added: 0002733
02-07-08 13:18 ferg Assigned To  => ferg
02-07-08 13:18 ferg Status new => closed
02-07-08 13:18 ferg Resolution open => fixed
02-07-08 13:18 ferg Fixed in Version  => 3.1.5


Mantis 1.0.0rc3[^]
Copyright © 2000 - 2005 Mantis Group
30 total queries executed.
26 unique queries executed.
Powered by Mantis Bugtracker