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]