I have been working on getting session replication working with some web applications that use cross context dispatching. In this case it is uPortal and JSR-168 portlets running via the Jakarta Pluto portlet container.

Session replication is working as expected with uPortal. Portlets on the other hand are not having their sessions replicated. In this application configuration the follow calls are happening. The browser makes a request to tomcat for the uPortal web application. While uPortal is rendering it makes cross context dispatch calls to servlets in the portlet web applications to render the results in the portal's response.

After some digging and stack traces to figure out how session replication in tomcat is implemented I've determined why the portlet applications are not having their sessions replicated. It appears that there is a ReplicationValve which is enabled by the presence of the <Cluster> tag in Tomcat's server.xml. This valve is only present in the stack for a direct call to the container and is not present in a cross context dispatched call.

I would like to work with the Tomcat developers to implement the ability for cross context calls to also notify the session manager that replication should be considered for the context.

I am prepared to do the work for this task but would like to get some feed back from the tomcat developer community on recommendations and in what way the work could be done to ensure its eventual inclusion in the tomcat codebase.

Thank you,
  Eric Dalquist


Below are the stack traces I captures when looking into the issue.


The following is a stack trace of a request being made to uPortal. You can see the ReplicationValve class which the request is passing through 7 items down.
Thread [TP-Processor3] (Suspended)
PortalSessionManager(HttpServlet).service(ServletRequest, ServletResponse) line: 802 ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 252 ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 173
 StandardWrapperValve.invoke(Request, Response) line: 213
 StandardContextValve.invoke(Request, Response) line: 178
 StandardHostValve.invoke(Request, Response) line: 126
 ReplicationValve.invoke(Request, Response) line: 145
 ErrorReportValve.invoke(Request, Response) line: 105
 StandardEngineValve.invoke(Request, Response) line: 107
 CoyoteAdapter.service(Request, Response) line: 148
 JkCoyoteHandler.invoke(Msg, MsgContext) line: 307
 HandlerRequest.invoke(Msg, MsgContext) line: 385
 ChannelSocket.invoke(Msg, MsgContext) line: 748
 ChannelSocket.processConnection(MsgContext) line: 678
 SocketConnection.runIt(Object[]) line: 871

After the portal completes servicing of the request the ReplicationValve performs the replication call (SimpleTcpReplicationManager.requestCompleted(String)) for the context. Thread [TP-Processor3] (Suspended (breakpoint at line 242 in SimpleTcpReplicationManager))
 SimpleTcpReplicationManager.requestCompleted(String) line: 242
 ReplicationValve.invoke(Request, Response) line: 206
 ErrorReportValve.invoke(Request, Response) line: 105
 StandardEngineValve.invoke(Request, Response) line: 107
 CoyoteAdapter.service(Request, Response) line: 148
 JkCoyoteHandler.invoke(Msg, MsgContext) line: 307
 HandlerRequest.invoke(Msg, MsgContext) line: 385
 ChannelSocket.invoke(Msg, MsgContext) line: 748
 ChannelSocket.processConnection(MsgContext) line: 678
 SocketConnection.runIt(Object[]) line: 871



The following is a request to uPortal that also interacts with a portlet. Looking far enough down the stack you see the base is the same as the first example stack. The 9th item down in the stack is the last uPortal class (CPortletAdapter) that gets used to call the portlet. The next 3 items are pluto classes that get the cross context request dispatcher and call it (ApplicationDispatcher.include(ServletRequest, ServletResponse) line: 499). The top of the stack is the last tomcat class that gets called before Pluto's PortletServlet gets executed.
Thread [TP-Processor3] (Suspended)
ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 234 ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 173
 ApplicationDispatcher.invoke(ServletRequest, ServletResponse) line: 672
ApplicationDispatcher.doInclude(ServletRequest, ServletResponse) line: 574
 ApplicationDispatcher.include(ServletRequest, ServletResponse) line: 499
PortletInvokerImpl.invoke(PortletRequest, PortletResponse, Integer) line: 120
 PortletInvokerImpl.action(ActionRequest, ActionResponse) line: 68
PortletContainerImpl.processPortletAction(PortletWindow, HttpServletRequest, HttpServletResponse) line: 150
 CPortletAdapter.setRuntimeData(ChannelRuntimeData, String) line: 578
MultithreadedPrivilegedCacheableDirectResponseCharacterChannelAdapter(MultithreadedCharacterChannelAdapter).setRuntimeData(ChannelRuntimeData) line: 29 ChannelManager.feedRuntimeDataToChannel(IChannel, HttpServletRequest) line: 896 ChannelManager.processRequestChannelParameters(HttpServletRequest) line: 841 ChannelManager.startRenderingCycle(HttpServletRequest, HttpServletResponse, UPFileSpec) line: 981 UserInstance.processPortletActionIfNecessary(HttpServletRequest, HttpServletResponse) line: 203 UserInstance.writeContent(HttpServletRequest, HttpServletResponse) line: 177 PortalSessionManager.doGet(HttpServletRequest, HttpServletResponse) line: 253 PortalSessionManager(HttpServlet).service(HttpServletRequest, HttpServletResponse) line: 689 PortalSessionManager(HttpServlet).service(ServletRequest, ServletResponse) line: 802 ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 252 ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 173
 StandardWrapperValve.invoke(Request, Response) line: 213
 StandardContextValve.invoke(Request, Response) line: 178
 StandardHostValve.invoke(Request, Response) line: 126
 ReplicationValve.invoke(Request, Response) line: 145
 ErrorReportValve.invoke(Request, Response) line: 105
 StandardEngineValve.invoke(Request, Response) line: 107
 CoyoteAdapter.service(Request, Response) line: 148
 JkCoyoteHandler.invoke(Msg, MsgContext) line: 307
 HandlerRequest.invoke(Msg, MsgContext) line: 385
 ChannelSocket.invoke(Msg, MsgContext) line: 748
 ChannelSocket.processConnection(MsgContext) line: 678
 SocketConnection.runIt(Object[]) line: 871

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to