You are viewing a plain text version of this content. The canonical link for it is here.
Posted to pluto-dev@portals.apache.org by "Wayne Holder (JIRA)" <pl...@jakarta.apache.org> on 2005/03/14 23:26:09 UTC

[jira] Created: (PLUTO-114) Session handling and the servlet spec.

Session handling and the servlet spec.
--------------------------------------

         Key: PLUTO-114
         URL: http://issues.apache.org/jira/browse/PLUTO-114
     Project: Pluto
        Type: Bug
  Components: general  
    Versions: 1.0.1-rc2    
    Reporter: Wayne Holder


I'm not quite sure how to address this issue, but I've come to believe that the basic design of JSR-168 places it in conflict with section SRV.7.3 (Session Scope) of the servlet spec. (version 2.4), which states:

"HttpSession objects must be scoped at the application (or servlet context) level.  The underlying mechanism, such as the cookie used to establish the session, can be the same for different contexts, but the object referenced, including the attributes in that object, must never be shared between contexts by the container. To illustrate this requirement with an example: if a servlet uses the RequestDispatcher to call a servlet in another Web application, any sessions created for and visible to the servlet being called must be different from those visible to the calling servlet."

But, to explain my concerns, let me illustrate by means of an example.  First, since the basic implementation of Pluto has it running as a web app, a typical portal might look like this:

  webapps/
    pluto
    app1
    app2

where app1 and app2 are two different web apps each containing one or more portlets.  (In my case, my company is one of several vendors who will be contributing portlets to a portal site, so our deliverable will be a WAR file containing a set of portlets and related servlets.  Therefore, each vendor contributing to the portal will package their portlets in a separate web app to avoid collisions with servlet names, html files, included jars, etc.)

One way to think about what section SRV.7.3 says, means it should be pretty much impossible for the portlets in either app1 or app2 to interact via session data in any meaningful way.  Specifically, a login portlet, or a state selector portlet in app1 will be unable to pass the login or currently-selected state information to a portlet in app2.

But, of course, this view overlooks the fact that Pluto is, itself, a separate web app which uses a RequestDispatcher to call the portlets in app1 and app2.  From this perspective, the portlets in app1 and app2 are really part of Pluto's context and, therefore, should be able to share session state.  But, here you can notice the lack of clarity in what section SRV.7.3 says.  In one place it talks about how the session object "must never be shared between contexts" but then, in the example that follows, it talks about calling a servlet in "another Web application."  So, to me it seems unclear whether the "context" (established by the context path, such as /pluto) or the "web app" (the unpacked app1 and app2 WAR files) is the dividing line.

This gets even harder to understand when you look at what's returned by a call to a PortletRequest's getContextPath() method.  In my tests, this method typically tells the portlet that it's context is the same as the web app in which it's deployed.  In this case, that's either /app1 or /app2, and not /pluto, as might be expected if you side with the idea that a portlet's context should be the same as Pluto's context for the portal.  And, it's even harder to reconcile what's going on when you try to make a portlet generate HTML that references a servlet in the same web app.

To elaborate on this last point, consider a portlet and a servlet, both defined in app1.  The portlet code looks like this:

public class TestPortlet extends GenericPortlet {
  protected void doView (RenderRequest request, RenderResponse response)
      throws PortletException, IOException {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    PortletSession pSes = request.getPortletSession();
    pSes.setAttribute("SESSION_VAL", "Here it is", PortletSession.APPLICATION_SCOPE);
    String servlet = request.getContextPath() + "/TestServlet";
    out.println("<iframe src=\"" + servlet + "\" width=\"300\" height=\"60\"></iframe>");
  }
}

and the servlet code looks like this:

public class TestServlet extends HttpServlet {
  blic void doGet (HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException {
    HttpSession session = request.getSession();
    String sVal = (String) session.getAttribute("SESSION_VAL");
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    out.println("<HTML><BODY>" + sVal + "</BODY></HTML>");
  }
}

The idea here is that TestPortlet generates HTML that defines an <iframe> tag that contains a URL in the src attribute that calls TestServlet to produce the content of the iframe.  Notice that TestPortlet calls getContextPath() to generate the URL that invokes TestServlet and (in my tests) will be told that it's running in the /app1 context.  If this is really true, and if the intent of section SRV.7.3 of the servlet spec is to say that web apps in the same context should be able to share session state, then this should work.  But, with Tomcat's default settings, it does not.  To make it work (at least, appear to work) I have to run Tomcat 5.5 and pull some other tricks (more details on this at my blog at http://weblogs.java.net/blog/wholder/archive/2005/02/session_session.html).

After I wrote that blog entry, I thought I had resolved this issue.  But, just recently, it came back again when I started to read some discussions in the Tomcat group related to Tomcat 5.5's "emptySessionPath" attribute.  Specicically, this thread:

  http://www.mail-archive.com/tomcat-dev@jakarta.apache.org/msg68146.html

After reading this thread, I had a short email exchange with Rémy Maucherat, the developer of the "emptySessionPath" code, to try and claify how it worked.  His final reply was:

"Different web applications will get separate session objects, this is normal. emptySessionPath does not change anything related to that."

Yet, Rémy's opinion seems to conflict with my observation that a portlet cannot use the session to pass information to a servlet in the same web app (deployed jar file) unless I set emptySessionPath to true.  That is, it's in conflict if I assume Rémy means that context is established by the unpacked jar file and not by the context path.  Hmm... now I'm even more confused.

But, all of this confusion seems to be telling me that session management in JSR-128 wasn't really thought through all that well.  Or, perhaps Tomcat interpreted the servlet spec one way, and JSR-168 group interpreted it another.  Or, is it just me?  Am I missing something here, or is portlet session handling really as bizarrre as it seems to be?

Wayne

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
If you want more information on JIRA, or have a bug to report see:
   http://www.atlassian.com/software/jira


[jira] Closed: (PLUTO-114) Session handling and the servlet spec.

Posted by "David DeWolf (JIRA)" <pl...@jakarta.apache.org>.
     [ http://issues.apache.org/jira/browse/PLUTO-114?page=history ]
     
David DeWolf closed PLUTO-114:
------------------------------

    Resolution: Invalid

This is not a bug, it is a discussion point.  Please bring this up on the user or developer lists. It has been discussed there before so you may be able to find some references in the mail archives as well.

> Session handling and the servlet spec.
> --------------------------------------
>
>          Key: PLUTO-114
>          URL: http://issues.apache.org/jira/browse/PLUTO-114
>      Project: Pluto
>         Type: Bug
>   Components: general
>     Versions: 1.0.1-rc2
>     Reporter: Wayne Holder

>
> I'm not quite sure how to address this issue, but I've come to believe that the basic design of JSR-168 places it in conflict with section SRV.7.3 (Session Scope) of the servlet spec. (version 2.4), which states:
> "HttpSession objects must be scoped at the application (or servlet context) level.  The underlying mechanism, such as the cookie used to establish the session, can be the same for different contexts, but the object referenced, including the attributes in that object, must never be shared between contexts by the container. To illustrate this requirement with an example: if a servlet uses the RequestDispatcher to call a servlet in another Web application, any sessions created for and visible to the servlet being called must be different from those visible to the calling servlet."
> But, to explain my concerns, let me illustrate by means of an example.  First, since the basic implementation of Pluto has it running as a web app, a typical portal might look like this:
>   webapps/
>     pluto
>     app1
>     app2
> where app1 and app2 are two different web apps each containing one or more portlets.  (In my case, my company is one of several vendors who will be contributing portlets to a portal site, so our deliverable will be a WAR file containing a set of portlets and related servlets.  Therefore, each vendor contributing to the portal will package their portlets in a separate web app to avoid collisions with servlet names, html files, included jars, etc.)
> One way to think about what section SRV.7.3 says, means it should be pretty much impossible for the portlets in either app1 or app2 to interact via session data in any meaningful way.  Specifically, a login portlet, or a state selector portlet in app1 will be unable to pass the login or currently-selected state information to a portlet in app2.
> But, of course, this view overlooks the fact that Pluto is, itself, a separate web app which uses a RequestDispatcher to call the portlets in app1 and app2.  From this perspective, the portlets in app1 and app2 are really part of Pluto's context and, therefore, should be able to share session state.  But, here you can notice the lack of clarity in what section SRV.7.3 says.  In one place it talks about how the session object "must never be shared between contexts" but then, in the example that follows, it talks about calling a servlet in "another Web application."  So, to me it seems unclear whether the "context" (established by the context path, such as /pluto) or the "web app" (the unpacked app1 and app2 WAR files) is the dividing line.
> This gets even harder to understand when you look at what's returned by a call to a PortletRequest's getContextPath() method.  In my tests, this method typically tells the portlet that it's context is the same as the web app in which it's deployed.  In this case, that's either /app1 or /app2, and not /pluto, as might be expected if you side with the idea that a portlet's context should be the same as Pluto's context for the portal.  And, it's even harder to reconcile what's going on when you try to make a portlet generate HTML that references a servlet in the same web app.
> To elaborate on this last point, consider a portlet and a servlet, both defined in app1.  The portlet code looks like this:
> public class TestPortlet extends GenericPortlet {
>   protected void doView (RenderRequest request, RenderResponse response)
>       throws PortletException, IOException {
>     response.setContentType("text/html");
>     PrintWriter out = response.getWriter();
>     PortletSession pSes = request.getPortletSession();
>     pSes.setAttribute("SESSION_VAL", "Here it is", PortletSession.APPLICATION_SCOPE);
>     String servlet = request.getContextPath() + "/TestServlet";
>     out.println("<iframe src=\"" + servlet + "\" width=\"300\" height=\"60\"></iframe>");
>   }
> }
> and the servlet code looks like this:
> public class TestServlet extends HttpServlet {
>   blic void doGet (HttpServletRequest request, HttpServletResponse response) 
>       throws ServletException, IOException {
>     HttpSession session = request.getSession();
>     String sVal = (String) session.getAttribute("SESSION_VAL");
>     response.setContentType("text/html");
>     PrintWriter out = response.getWriter();
>     out.println("<HTML><BODY>" + sVal + "</BODY></HTML>");
>   }
> }
> The idea here is that TestPortlet generates HTML that defines an <iframe> tag that contains a URL in the src attribute that calls TestServlet to produce the content of the iframe.  Notice that TestPortlet calls getContextPath() to generate the URL that invokes TestServlet and (in my tests) will be told that it's running in the /app1 context.  If this is really true, and if the intent of section SRV.7.3 of the servlet spec is to say that web apps in the same context should be able to share session state, then this should work.  But, with Tomcat's default settings, it does not.  To make it work (at least, appear to work) I have to run Tomcat 5.5 and pull some other tricks (more details on this at my blog at http://weblogs.java.net/blog/wholder/archive/2005/02/session_session.html).
> After I wrote that blog entry, I thought I had resolved this issue.  But, just recently, it came back again when I started to read some discussions in the Tomcat group related to Tomcat 5.5's "emptySessionPath" attribute.  Specicically, this thread:
>   http://www.mail-archive.com/tomcat-dev@jakarta.apache.org/msg68146.html
> After reading this thread, I had a short email exchange with Rémy Maucherat, the developer of the "emptySessionPath" code, to try and claify how it worked.  His final reply was:
> "Different web applications will get separate session objects, this is normal. emptySessionPath does not change anything related to that."
> Yet, Rémy's opinion seems to conflict with my observation that a portlet cannot use the session to pass information to a servlet in the same web app (deployed jar file) unless I set emptySessionPath to true.  That is, it's in conflict if I assume Rémy means that context is established by the unpacked jar file and not by the context path.  Hmm... now I'm even more confused.
> But, all of this confusion seems to be telling me that session management in JSR-128 wasn't really thought through all that well.  Or, perhaps Tomcat interpreted the servlet spec one way, and JSR-168 group interpreted it another.  Or, is it just me?  Am I missing something here, or is portlet session handling really as bizarrre as it seems to be?
> Wayne

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
If you want more information on JIRA, or have a bug to report see:
   http://www.atlassian.com/software/jira