Search code examples
javajspscriptlet

Can not return a value to the screen from method in Scriptlet


I need to display to the screen some values which are read in method defined in the script-let. The code below does not compiles:

<%!
    void displayRecursively(KnowledgeElement ke, ExtendsRelationshipService ers){
        List<ExtendsRelationship> erList = null;
        %><%=ke.getName()%><br /><%!
        try {
            erList = ers.findIncomingExtendsKERelationships(ke);
        } catch (Exception e) {}
        if (erList!=null){
            for (ExtendsRelationship er : erList){
                KnowledgeElement startKe = er.getStartKE();
                displayRecursively(startKe,ers);
            }
        }
    } 
%>  

<%
    KnowledgeElement ke = null;
    ke = (KnowledgeElement)request.getAttribute("knowledgeElement");
    ExtendsRelationshipService ers = (ExtendsRelationshipService)request.getAttribute("ers");
    displayRecursively(ke,ers);             
%>

The compilation error is:

PWC6199: Generated servlet error:
cannot find symbol
  symbol:   variable ke
  location: class org.apache.jsp.WEB_002dINF.ke_jsp

With .. %><%=ke.getName()%><% .. does not compiles as well. Can someone please suggest how to resolve this?


Solution

  • Servlet containers compile JSP code into servlet classes following this approach:

    • When using the "<%! ... %>" scriptlet symbols you are defining code that is going to be part of the servlet class itself, which allows you to define functions.
    • When using the "<% ... %>" scriptlet symbols you are defining code that is going to be part of the "service" method of the servlet itself.

    So, what you are doing is mixing code that is being declared outside the "service" method with a reference to variable that is going to be copied inside the "service" method.

    To solve your problem I would add another parameter to your function and replace that "cross-reference" (or whatever it should be called). It would look like this:

    <%!
        void displayRecursively(JspWriter out, KnowledgeElement ke, ExtendsRelationshipService ers){
            List<ExtendsRelationship> erList = null;
            out.print(ke.getName());
            out.println("<br />");
            try {
                erList = ers.findIncomingExtendsKERelationships(ke);
            } catch (Exception e) {}
            if (erList!=null){
                for (ExtendsRelationship er : erList){
                    KnowledgeElement startKe = er.getStartKE();
                    displayRecursively(out, startKe,ers);
                }
            }
        } 
      %>
    

    When invoking that function in your other scriptlet you must past in the reference to the PrintWriter (which is an implicit variable for scriptlets that go inside the "service" method):

    displayRecursively(out, ke, era);
    

    Just notice that you will need page import of the "JspWriter" class in your JSP in order to compile.