Sunday, January 13, 2013

JSP Limitation and Exception when add a line



Have you ever encounter with the limit of JSP file or exception when you try to add even single line in JSP file? In my experience there was such challenging and interesting work to write few lines in JSP page. The funny thing was the contents of JSP were too large to add even single line. Before explaining how I handled this problem let me tell you what happens when you write a code in JSP file.
All of you know that the code written in JSP file using JSP directive <% %> it goes inside _jspService method. But I’d like to add one more point here, though its goes to _jspService method but inside single try catch block, this is the point where there is twist on the tail.
Let’s take a look.
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Test1</title>
<script type="text/javascript">
       function sayHello(name){
              alert("Welcome " + name);
             
       }
       function sayThank(){
              alert("Thanks..");
       }
</script>
</head>
<body>
       <script type="text/javascript">
              sayHello('shail');
              sayThank();
       </script>
</body>
</html>
Now when you deploy this JSP in web container and call, this file get converted in pure java file which will have _jspService method as below
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
        throws java.io.IOException, javax.servlet.ServletException {

    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session = null;
    final javax.servlet.ServletContext application;
    final javax.servlet.ServletConfig config;
    javax.servlet.jsp.JspWriter out = null;
    final java.lang.Object page = this;
    javax.servlet.jsp.JspWriter _jspx_out = null;
    javax.servlet.jsp.PageContext _jspx_page_context = null;


    try {
      response.setContentType("text/html; charset=ISO-8859-1");
      pageContext = _jspxFactory.getPageContext(this, request, response,
                     null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write("\r\n");
      out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n");
      out.write("<html>\r\n");
      out.write("<head>\r\n");
      out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\">\r\n");
      out.write("<title>Test1</title>\r\n");
      out.write("<script type=\"text/javascript\">\r\n");
      out.write("\tfunction sayHello(name){\r\n");
      out.write("\t\talert(\"Welcome \" + name);\r\n");
      out.write("\t\t\r\n");
      out.write("\t}\r\n");
      out.write("\tfunction sayThank(){\r\n");
      out.write("\t\talert(\"Thanks..\");\r\n");
      out.write("\t}\r\n");
      out.write("</script>\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");
      out.write("\t<script type=\"text/javascript\">\r\n");
      out.write("\t\tsayHello('shail');\r\n");
      out.write("\t\tsayThank();\r\n");
      out.write("\t</script>\r\n");
      out.write("</body>\r\n");
      out.write("</html>");
    } catch (java.lang.Throwable t) {
      if (!(t instanceof javax.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try { out.clearBuffer(); } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
        else throw new ServletException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
Now if you count how many out.write statements are inside try block? You will find 23. Specially look immediate after yellow marked line. You will find there is one empty line in JSP file which has taken a line in java file marked in Red Color. Let’s look at another program with same functionality.
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Test2</title>
<script type="text/javascript" src="js/j1.js"></script>
</head>
<body>
       <script type="text/javascript">
              sayHello('shail');
              sayThank();
       </script>
</body>
</html>
and JS folder have js1.js file which contents are as below
function sayHello(name){

       alert("Welcome " + name);
      
       alert("wait..");

}
function sayThank(){
      
       alert("Thanks..");
      
}

Now when you deploy this file and run it, this will be converted in Java file as below
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
        throws java.io.IOException, javax.servlet.ServletException {

    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session = null;
    final javax.servlet.ServletContext application;
    final javax.servlet.ServletConfig config;
    javax.servlet.jsp.JspWriter out = null;
    final java.lang.Object page = this;
    javax.servlet.jsp.JspWriter _jspx_out = null;
    javax.servlet.jsp.PageContext _jspx_page_context = null;

    try {
      response.setContentType("text/html; charset=ISO-8859-1");
      pageContext = _jspxFactory.getPageContext(this, request, response,
                     null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write("\r\n");
      out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n");
      out.write("<html>\r\n");
      out.write("<head>\r\n");
      out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\">\r\n");
      out.write("<title>Test2</title>\r\n");
      out.write("<script type=\"text/javascript\" src=\"js/j1.js\"></script>\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");
      out.write("\t<script type=\"text/javascript\">\r\n");
      out.write("\t\tsayHello('shail');\r\n");
      out.write("\t\tsayThank();\r\n");
      out.write("\t</script>\r\n");
      out.write("</body>\r\n");
      out.write("</html>");
    } catch (java.lang.Throwable t) {
      if (!(t instanceof javax.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try { out.clearBuffer(); } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
        else throw new ServletException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
Now if you count how many out.write statements are inside above try block? You will find 15 and total difference between Test1_jsp.java and Test2_jsp.java are 8 lines. If you see closely, you will find there are much empty lines in JS file than Test1.jsp but converted java file has no such line.
Is it matter? My answer will be Yes. When you write as much as line in JSP file inside <% %> it goes to single try-catch block of _jspService method. Do you know there is a size limit of try-catch block i.e. 32K. So before writing code inside JSP, you should be careful.

Use following tips to avoid limit error
Ø  Write all java script in different file and instead of including this file use
<script type="text/javascript" src="js/j1.js"></script>

Ø  If there are a large volume of java code inside JSP. Create different method using <%! %> block, so that a separate method will be created and you can call this method.
<%!
          public void go(){
                 System.out.println("Hello");
          }
%>

Ø  Avoid empty line in JSP file.
Ø  Small html tag can be combined in single line.




That’s all,
Thanks J