scope of declarations?

Discussions

Web tier: servlets, JSP, Web frameworks: scope of declarations?

  1. scope of declarations? (1 messages)

    what is the scope of a var declared in a JSP declarations using <%!

    container? servlet? page? package?

    thx much
    -pan


    Threaded Messages (1)

  2. scope of declarations?[ Go to top ]

    A great question, and one that bit my team not long ago.
    To find the answer, try this experiment:

    As you know, a JSP is compiled into a Java Servlet when it is requested,
    (the firs time, and later if it has changed). Looking at the generated
    Servlet source code is a really great way to answer questions like this.

    A variable declared in a JSP declaration ends up appearing at the top
    of the generated Servlet, while a variable declared in a JSP scriplet
    appears in the service method. This means that if you use the declaration
    syntax, you end up with one copy of the variable per Servlet instance...
    under normal circumstances, this means multiple users will "share" it
    (perhaps useful for hit counters).

    With a scriptlet variable, each request gets its own copy (which is more
    often what you want).

    To illustrate this, you can do a quick experiment with the J2EE SDK 1.2.1,
    free from Sun. I also tried the same thing with WebLogic 4.5.1, with the same
    results, but let's use the J2EE SDK here.

    Create two short JSPs in j2skdee1.2.1/public_html:

    my_declaration.jsp:
    ----------------------
    <%! int foo = 1; %>

    Hello!
    ----------------------

    and my_declaration.jsp:
    ----------------------
    <% int foo = 1; %>

    Hello!
    ----------------------


    Now start the "j2ee" server, and request the two files in your browser.
    In both cases, you'll just see "Hello!", but the important thing is we've
    generated the Servlet. By default, the J2EE SDK keeps the generated java
    source for you to examine (for WebLogic, use the "keepgenerated=true" option
    in weblogic.properties).

    Go to: j2sdkee1.2.1/repository/<hostname>/web

    Note the two .java files. I've included them up to the point our variable,
    "foo", appears.

    From the one named something like
    _0002fmy_0005fdeclaration_0002ejspmy_0005fdeclaration_jsp_0.java:

    ----------------------------------------------------------------------------------------------------
       public class _0002fmy_0005fdeclaration_0002ejspmy_0005fdeclaration_jsp_0 extends HttpJspBase {

        // begin [file="/my_declaration.jsp";from=(0,3);to=(0,17)]
             int foo = 1;
        // end

        static {
        }
        public _0002fmy_0005fdeclaration_0002ejspmy_0005fdeclaration_jsp_0( ) {
        }

        private static boolean _jspx_inited = false;

        public final void _jspx_init() throws JasperException {
        }

        public void _jspService(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
    ----------------------------------------------------------------------------------------------------

    And the one named something like
    _0002fmy_0005fscriptlet_0002ejspmy_0005fscriptlet_jsp_0.java:

    ----------------------------------------------------------------------------------------------------
    public class _0002fmy_0005fscriptlet_0002ejspmy_0005fscriptlet_jsp_0 extends HttpJspBase {


        static {
        }
        public _0002fmy_0005fscriptlet_0002ejspmy_0005fscriptlet_jsp_0( ) {
        }

        private static boolean _jspx_inited = false;

        public final void _jspx_init() throws JasperException {
        }

        public void _jspService(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {

            JspFactory _jspxFactory = null;
            PageContext pageContext = null;
            HttpSession session = null;
            ServletContext application = null;
            ServletConfig config = null;
            JspWriter out = null;
            Object page = this;
            String _value = null;
            try {

                if (_jspx_inited == false) {
                    _jspx_init();
                    _jspx_inited = true;
                }
                _jspxFactory = JspFactory.getDefaultFactory();
                response.setContentType("text/html;charset=8859_1");
                pageContext = _jspxFactory.getPageContext(this, request, response,
                            "", true, 8192, true);

                application = pageContext.getServletContext();
                config = pageContext.getServletConfig();
                session = pageContext.getSession();
                out = pageContext.getOut();

                // begin [file="/my_scriptlet.jsp";from=(0,2);to=(0,16)]
                     int foo = 1;
    ----------------------------------------------------------------------------------------------------


    See what I mean? I am not sure why the JSP spec is so vague about this. A few JSP
    books I've read mention this, but it's usually buried in the middle somewhere.

    In either case, the variable would be available only in the JSP you placed it,
    but using the declaration syntax definitely has this "interesting" behavior and
    I thought I should mention it. Can anyone else comment on this?

    Hope this helps.

    -Marc