1
votes

I recently upgraded from jetty 9.3.11 to 9.4.6 . Since 9.4.x does not support HashSessionManager, I created my own custom SessionHandler. But when i attach this SessionHandler to the WebAppContext then the context becomes null when trying to access from servlets. there are no errors thrown in the logs.

Relevant section of code:

MyCustomSessionHandler sessionHandler = new MyCustomSessionHandler();
HandlerCollection handlers_ = new HandlerCollection(true);
COntextHandlerCollection chc_ = new ContextHandlerCollection();
for(WebAppConfig wap: webAppConfigs)   //webappconfig a POJO from where I am getting webapp configs
{
  String path = wap.getPath();
  String warFile = wap.getWarFile(); 
  WebAppContext context = 
    new WebAppContext(chc_, warFile, path);
  // context.setSessionHandler(new SessionHandler());  // this one works.
  context.setSessionHandler(sessionHandler);  // this one doesnt work.
  for (ServletConfig servletConfig: wap.getServletConfigs())  //ServletConfig is another POJO to get servlet configs
  {
    String servletName = servletConfig.getName();
    String servletPath = servletConfig.getPath();
    Servlet servlet = servletConfig.getServlet();   
    ServletHolder servletHolder = new ServletHolder(servlet);
    context.addServlet(servletHolder, servletPath);
  }
}
handlers_.setHandlers(new Handler[] { chc_, new DefaultHandler()});
server_.setHandler(handlers_);

Sample of my custom Session handler

public class MyCUstomSessionHandler extends SessionHandler
{
  public MyCustomSessionHandler()
  {
    super();
  }

  public void setSecureCookies(boolean secureCookies)
  {
    getSessionCookieConfig().setSecure(secureCookies);
  }

  public void setHttpOnly(boolean httpOnly)
  {
    getSessionCookieConfig().setHttpOnly(httpOnly);
  }

  public void setMaxCookieAge(int age)
  {
    getSessionCookieConfig().setMaxAge(age);
  }

}

Further clarification: It happens because I create a singleton sessionhandler and share it across different WepAppContext as a way of sharing sessions among them. This method seemed work fine without issues in 9.3 but doesn't work with new session management in 9.4.

Any help to solve this problem is appreciated.

1

1 Answers

1
votes

I solved it by

  1. setting cookie path to root ("/")

  2. extending the getSession() function of SessionHandler to loop through all the contexts to check if session is created for the cookie in any other context.

/* check all contexts for sessions*/

public Session getSession(String id)
{
  Session session = getLocalSession(id);
  if (session == null)
  {
    for (SessionHandler manager: getSessionIdManager().getSessionHandlers())
    {
      if (manager.equals(this) || 
        !(manager instanceof CustomSessionHandler))
      {
        continue;
      }
      session =  ((CustomSessionHandler)manager).getLocalSession(id);
      if (session != null)
      {
        break;
      }
    }
    // should we duplicate sessions in each context?
    // will we end up with inconsistent sessions?
    /*
    if (externalSession != null)
    {
      try
      {
        getSessionCache().put(id, externalSession);
      }
      catch (Exception e)
      {
        LOG.warn("Unable to save session to local cache.");
      }
    }
    */
  }
  
  return session;
}

/* ------------------------------------------------------------ */
/**
 * Get a known existing session
 * @param id The session ID stripped of any worker name.
 * @return A Session or null if none exists.
 */
public Session getLocalSession(String id)
{
  return super.getSession(id);
}