Gotcha. Well I'm still confused, but I do have a suggestion. Instead of catching and handling exceptions like this in your page, let them propagate out and handle them when Wicket calls your RequestCycleListener#onException(). No point in finishing the page construction/rendering, right?
On Wed, Dec 7, 2011 at 4:27 PM, Fang Lin <[email protected]> wrote: > Not sure if the exception occurs at the commit/detach phase of a request. > The session is always verified before generating the page content. See the > stack trace: > [m.p.BasePage] > edu.washington.cac.myuw.servlet.session.NoExistingSessionException: An > existing user but the HttpSession is null > at edu.washington.cac.myuw.servlet.session.UwSession.<init>(Unknown > Source) > at myuw.sessiono.MyUWSession.<init>(Unknown Source) > at myuw.session.MyuwSession.setMyUWSession(Unknown Source) > at myuw.page.BasePage.setMyUWSession(Unknown Source) > at myuw.page.BasePage.setup(Unknown Source) > at myuw.page.Main.<init>(Unknown Source) > at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native > Method) > at > sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) > at > sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) > at java.lang.reflect.Constructor.newInstance(Constructor.java:513) > at > org.apache.wicket.session.DefaultPageFactory.newPage(DefaultPageFactory.java:173) > at > org.apache.wicket.session.DefaultPageFactory.newPage(DefaultPageFactory.java:97) > at > org.apache.wicket.session.DefaultPageFactory.newPage(DefaultPageFactory.java:47) > at > org.apache.wicket.DefaultMapperContext.newPageInstance(DefaultMapperContext.java:107) > at > org.apache.wicket.request.handler.PageProvider.resolvePageInstance(PageProvider.java:264) > at > org.apache.wicket.request.handler.PageProvider.getPageInstance(PageProvider.java:165) > at > org.apache.wicket.request.handler.ListenerInterfaceRequestHandler.getPage(ListenerInterfaceRequestHandler.java:100) > at > org.apache.wicket.request.handler.ListenerInterfaceRequestHandler.respond(ListenerInterfaceRequestHandler.java:165) > > > -----Original Message----- > From: Dan Retzlaff [mailto:[email protected]] > Sent: Wednesday, December 07, 2011 4:01 PM > To: [email protected] > Subject: Re: ConcurrentModificationException > > So it sounds like > 1. you've introduced a custom layer between Wicket and the servlet session, > 2. that custom layer can throw an exception called InvalidSession while > Wicket tries to save a page into it (during request cycle commit/detach), > and > 3. that exception gets into a handleException() method which calls > setResponsePage, adding a new request handler to the request cycle being > detached. > > If that's right, then it's probably worth mentioning that the commit/detach > phase of a request is way too late to be changing response pages. The best > you can do at that point is log an exception. > > (Apologies if I misunderstand you; it sounds fairly unconventional but > maybe I just haven't pieced it together correctly.) > > On Wed, Dec 7, 2011 at 3:05 PM, Fang Lin <[email protected]> wrote: > > > That's very helpful. Thanks for sharing your code! > > > > We use a custom session manager, which verifies the session. When the > > underline HttpSession is expired, it throws a sub-class of InvalidSession > > exception. > > > > All the Throwable in the WebPage is handled by this method: > > protected void handleException(Throwable e) > > { > > if (e instanceof InvalidSession) { > > setResponsePage(new SessionErr()); // <== gets triggered before > > Wicket's PageExpiredException > > return; > > } > > ErrPage.logErr (getLoggerId(), > > e.toString(), > > getHttpServletRequest()); > > if (e instanceof ParameterException) { > > setResponsePage(new ParamErr()); > > return; > > } > > setResponsePage(new InternalErr()); > > return; > > } > > > > > > public class SessionErr extends WebPage { > > public SessionErr () > > { > > super (); > > getRequestCycle().replaceAllRequestHandlers (new > SessionErrHandler()); > > } > > } > > > > public class SessionErrHandler extends RedirectRequestHandler { > > public SessionErrHandler() > > { > > super(LOG_BACKIN_URL); > > } > > } > > > > > > > > > > -----Original Message----- > > From: Dan Retzlaff [mailto:[email protected]] > > Sent: Wednesday, December 07, 2011 1:56 PM > > To: [email protected] > > Subject: Re: ConcurrentModificationException > > > > If you want to get to the bottom of that CME, then I'd investigate usage > #1 > > since you've presented usages #2 and #3 and they look okay (barring a > > Wicket bug). > > > > In any case, I haven't been working with 1.5 very long but for what it's > > worth we have this as our custom RequestCycleListener: > > http://pastebin.com/SnS9PS8N > > > > Note that returning null allows Wicket to employ the registered > > PageExpiredErrorPage and AccessDeniedPage pages, and we set both to our > > Login page. The ErrorPage is our customized "oops" page for truly > > unexpected exceptions. > > > > On Wed, Dec 7, 2011 at 1:36 PM, Fang Lin <[email protected]> > wrote: > > > > > Hi Dan, > > > > > > > > > > > > Thanks for the response and the question! > > > > > > > > > > > > I have put exception handler in three places: > > > > > > > > > > > > 1. In the WebPage via a try and catch > > > > > > > > > > > > 2. In the custom RequestCycleListener > > > > > > > > > 3. In the ApplicationSettings > > > > > > > > > > > > Because I wasn't clear about the relationship between them, I put them > > > everywhere just in case. I was also wondering why handler got invoked > > twice. > > > > > > > > > > > > It looks like #2 and #3 are unnecessary/redundant unless they handles > > > different exceptions. > > > > > > What would be the recommended approach for exception handling? > > > > > > > > > > > > -Fang > > > > > > -----Original Message----- > > > From: Dan Retzlaff [mailto:[email protected]] > > > Sent: Wednesday, December 07, 2011 9:40 AM > > > To: [email protected] > > > Subject: Re: ConcurrentModificationException > > > > > > > > > > > > Hi Fang, > > > > > > > > > > > > Are there any other references to SessionErr page in your application > > aside > > > > > > from its registration in ApplicationSettings? I ask because, as Martin > > > > > > says, Wicket will only instantiate the PageExpiredErrorPage as a > default > > > > > > behavior if a custom RequestCycleListener does not provide an alternate > > > > > > handler. Since your RequestCycleListener *always* provides a handler, I > > > > > > don't see how the default behavior can apply. > > > > > > > > > > > > Even more confusing is how you can get CME at that location. It's like > > the > > > > > > SessionErr instantiation happens during the detach process. I'm just > not > > > > > > seeing how Wicket can do that itself. > > > > > > > > > > > > Dan > > > > > > > > > > > > On Tue, Dec 6, 2011 at 4:47 PM, Fang Lin <[email protected]> > > wrote: > > > > > > > > > > > > > Should I use scheduleRequestHandlerAfterCurrent instead of > > > > > > > replaceAllRequestHandlers ? > > > > > > > > > > > > > > -----Original Message----- > > > > > > > From: Fang Lin [mailto:[email protected]] > > > > > > > Sent: Tuesday, December 06, 2011 3:39 PM > > > > > > > To: [email protected] > > > > > > > Subject: RE: ConcurrentModificationException > > > > > > > > > > > > > > I have just run into the ConcurrentModificationException on my dev > > > server. > > > > > > > Not that I can reproduce it, but I got more details: > > > > > > > > > > > > > > 1. my session has expired > > > > > > > > > > > > > > 2. the PageExpiredErrorPage SessionErr was invoked. Internally it > > > > > > > executed this statement: > > > > > > > public SessionErr () > > > > > > > { > > > > > > > super (); > > > > > > > log.info ("Before replaceAllRequestHandlers"); > > > > > > > getRequestCycle().replaceAllRequestHandlers (new > > > SessionErrHandler()); > > > > > > > // <=========== > > > > > > > } > > > > > > > > > > > > > > 3. SessionErrHandler was created, > > > > > > > public SessionErrHandler() > > > > > > > { > > > > > > > super(LOG_BACKIN_URL); > > > > > > > log.info ("RedirectRequest"); > > > > > > > } > > > > > > > > > > > > > > Log: > > > > > > > INFO 06 15:23:58.755 Before replaceAllRequestHandlers > [m.p.SessionErr] > > > > > > > INFO 06 15:23:58.755 RedirectRequest [m.SessionErrHandler] INFO 06 > > > > > > > 15:23:58.760 Before replaceAllRequestHandlers [m.p.SessionErr] INFO > 06 > > > > > > > 15:23:58.760 RedirectRequest [m.SessionErrHandler] > > > > > > > > > > > > > > On the browser, HTTP Status 500 - > > > > > > > java.util.ConcurrentModificationException > > > > > > > > > > > > > > > > java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372) > > > > > > > java.util.AbstractList$Itr.next(AbstractList.java:343) > > > > > > > > > > > > > > > > > > > > > org.apache.wicket.request.RequestHandlerStack.detach(RequestHandlerStack.java:176) > > > > > > > > > > > > > > > > > > > > org.apache.wicket.request.cycle.RequestCycle.onDetach(RequestCycle.java:565) > > > > > > > > > > > > > > > > > > > > org.apache.wicket.request.cycle.RequestCycle.detach(RequestCycle.java:508) > > > > > > > > > > > > > > > > > > > > > org.apache.wicket.request.cycle.RequestCycle.processRequestAndDetach(RequestCycle.java:284) > > > > > > > > > > > > > > > > > > > > > org.apache.wicket.protocol.http.WicketFilter.processRequest(WicketFilter.java:162) > > > > > > > > > > > > > > > > > > > > org.apache.wicket.protocol.http.WicketFilter.doFilter(WicketFilter.java:218) > > > > > > > > > > > > > > -----Original Message----- > > > > > > > From: Fang Lin [mailto:[email protected]] > > > > > > > Sent: Tuesday, December 06, 2011 2:06 PM > > > > > > > To: [email protected] > > > > > > > Subject: RE: ConcurrentModificationException > > > > > > > > > > > > > > I have been trying to reproduce it on our dev server this morning, > but > > > > > > > could not. However I did run into it twice on our production server > > > > > > > yesterday. > > > > > > > > > > > > > > I wonder if you could answer my question "Is this exception handler > > > > > > > invoked before or after the ErrorPages ?" > > > > > > > > > > > > > > -----Original Message----- > > > > > > > From: Martin Grigorov [mailto:[email protected]] > > > > > > > Sent: Tuesday, December 06, 2011 12:47 PM > > > > > > > To: [email protected] > > > > > > > Subject: Re: ConcurrentModificationException > > > > > > > > > > > > > > No, I don't see anything wrong here. > > > > > > > If you are able to reproduce it then we can debug it. > > > > > > > > > > > > > > On Tue, Dec 6, 2011 at 9:40 PM, Fang Lin <[email protected]> > > > wrote: > > > > > > > > Thanks, Martin! > > > > > > > > > > > > > > > > In the init(), I have: > > > > > > > > { > > > > > > > > getMarkupSettings().setStripWicketTags(true); > > > > > > > > > > > > > > > > IApplicationSettings settings = getApplicationSettings(); > > > > > > > > settings.setAccessDeniedPage(AccessErr.class); > > > > > > > > settings.setPageExpiredErrorPage(SessionErr.class); > > > > > > > > settings.setInternalErrorPage(InternalErr.class); > > > > > > > > > > > > > > > > // #2 starts > > > > > > > > getRequestCycleListeners().add(new > AbstractRequestCycleListener() > > > > > > > > { > > > > > > > > > > > > > > > > public IRequestHandler onException(RequestCycle cycle, > > > > > > > > Exception e) > > > > > > > > { > > > > > > > > return new RedirectRequestHandler (ERROR_PAGE_URL); > > > > > > > > } > > > > > > > > }); > > > > > > > > // #2 ends > > > > > > > > } > > > > > > > > Could the #2 code block be the cause? Is this exception handler > > > invoked > > > > > > > before or after the ErrorPages ? > > > > > > > > > > > > > > > > Our authentication strategy is set up at Apache level. > > > > > > > > This is what SessionErr class does: > > > > > > > > getRequestCycle().replaceAllRequestHandlers (new > > SessionErrHandler()); > > > > > > > > > > > > > > > > And SessionErrHandler redirect to the Login Servlet. And the Login > > > > > > > Servlet will be routed to the WebLogin server. > > > > > > > > > > > > > > > > -----Original Message----- > > > > > > > > From: Martin Grigorov [mailto:[email protected]] > > > > > > > > Sent: Monday, December 05, 2011 11:59 PM > > > > > > > > To: [email protected] > > > > > > > > Subject: Re: ConcurrentModificationException > > > > > > > > > > > > > > > > Hi, > > > > > > > > > > > > > > > > I don't see how this may happen. > > > > > > > > The execution of RequestCycle is single threaded. > > > > > > > > Do you have RequestCycleListener or something similar where you > start > > > > > > > another thread and you use the same instance of RequestCycle ? > > > > > > > > > > > > > > > > On Tue, Dec 6, 2011 at 2:31 AM, Fang Lin <[email protected] > > > > > > > > > wrote: > > > > > > > >> When clicking on a link (i.e., ?5-1.ILinkListener-...) after a > > session > > > > > > > expired, this error page shows up on my browser window: > > > > > > > >> Exception report > > > > > > > >> message > > > > > > > >> description The server encountered an internal error () that > > prevented > > > > > > > it from fulfilling this request. > > > > > > > >> exception > > > > > > > >> java.util.ConcurrentModificationException > > > > > > > >> > > > > > > > >> > > java.util.AbstractList$Itr.checkForComodification(AbstractList.java:3 > > > > > > > >> 7 > > > > > > > >> 2) > > > > > > > >> > > > > > > > >> java.util.AbstractList$Itr.next(AbstractList.java:343) > > > > > > > >> > > > > > > > >> > > org.apache.wicket.request.RequestHandlerStack.detach(RequestHandlerSt > > > > > > > >> a > > > > > > > >> ck.java:176) > > > > > > > >> > > > > > > > >> > > org.apache.wicket.request.cycle.RequestCycle.onDetach(RequestCycle.ja > > > > > > > >> v > > > > > > > >> a:565) > > > > > > > >> > > > > > > > >> > > org.apache.wicket.request.cycle.RequestCycle.detach(RequestCycle.java: > > > > > > > >> 508) > > > > > > > >> > > > > > > > >> > > org.apache.wicket.request.cycle.RequestCycle.processRequestAndDetach( > > > > > > > >> R > > > > > > > >> equestCycle.java:284) > > > > > > > >> > > > > > > > >> > > org.apache.wicket.protocol.http.WicketFilter.processRequest(WicketFil > > > > > > > >> t > > > > > > > >> er.java:162) > > > > > > > >> > > > > > > > >> > > org.apache.wicket.protocol.http.WicketFilter.doFilter(WicketFilter.ja > > > > > > > >> v > > > > > > > >> a:218) > > > > > > > >> at > > > > > > > >> > > org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl > > > > > > > >> i > > > > > > > >> cationFilterChain.java:235) > > > > > > > >> at > > > > > > > >> > > org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF > > > > > > > >> i > > > > > > > >> lterChain.java:206) > > > > > > > >> at > > > > > > > >> > > org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperV > > > > > > > >> a > > > > > > > >> lve.java:233) > > > > > > > >> at > > > > > > > >> > > org.apache.catalina.core.StandardContextValve.invoke(StandardContextV > > > > > > > >> a > > > > > > > >> lve.java:191) > > > > > > > >> at > > > > > > > >> > > org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.j > > > > > > > >> a > > > > > > > >> va:127) > > > > > > > >> at > > > > > > > >> > > org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.j > > > > > > > >> a > > > > > > > >> va:102) > > > > > > > >> at > > > > > > > >> > > org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineVal > > > > > > > >> v > > > > > > > >> e.java:109) > > > > > > > >> at > > > > > > > >> > > org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.jav > > > > > > > >> a > > > > > > > >> :298) > > > > > > > >> at > > > > > > > >> > > org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:190) > > > > > > > >> at > > > > > > > >> > org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:291) > > > > > > > >> at > > > > > > > >> org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:774) > > > > > > > >> at > > > > > > > >> > > org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.ja > > > > > > > >> v > > > > > > > >> a:703) > > > > > > > >> at > > > > > > > >> > > org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSock > > > > > > > >> e > > > > > > > >> t.java:896) > > > > > > > >> at > > > > > > > >> > > org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadP > > > > > > > >> o > > > > > > > >> ol.java:690) > > > > > > > >> at java.lang.Thread.run(Thread.java:662) > > > > > > > >> This ConcurrentModificationException occurs about 70+ times on an > > > > > > > application server daily. > > > > > > > >> Wicket version 1.5.3. > > > > > > > >> Any suggestion on how to avoid this? > > > > > > > >> In the init method of sub-class of the WebApplication , I have: > > > > > > > >> IApplicationSettings settings = getApplicationSettings(); > > > > > > > >> settings.setAccessDeniedPage(AccessErr.class); > > > > > > > >> settings.setPageExpiredErrorPage(SessionErr.class); > > > > > > > >> settings.setInternalErrorPage(InternalErr.class); > > > > > > > >> When a session expired, should it invoke the PageExpiredErrorPage? > > > > > > > > > > > > > > > > Yes. You make a request to a page, Wicket searches for this page in > > the > > > > > > > stores, doesn't find it and throws PageExpiredException. > > > > > > > > But, if the request url has the mount path then Wicket will create > a > > > new > > > > > > > Page instance instead. If you have authentication strategy set up > then > > > you > > > > > > > go to the Login page, otherwise this page will be rendered. > > > > > > > > > > > > > > > > If you are able to reproduce the problem in a quickstart attach it > to > > > > > > > Jira so we can debug it. > > > > > > > > Thanks! > > > > > > > > > > > > > > > >> -Fang > > > > > > > >> > > > > > > > >> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > -- > > > > > > > > Martin Grigorov > > > > > > > > jWeekend > > > > > > > > Training, Consulting, Development > > > > > > > > http://jWeekend.com > > > > > > > > > > > > > > > > > --------------------------------------------------------------------- > > > > > > > > To unsubscribe, e-mail: [email protected] > > > > > > > > For additional commands, e-mail: [email protected] > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > -- > > > > > > > Martin Grigorov > > > > > > > jWeekend > > > > > > > Training, Consulting, Development > > > > > > > http://jWeekend.com > > > > > > > > > > > > > > --------------------------------------------------------------------- > > > > > > > To unsubscribe, e-mail: [email protected] > > > > > > > For additional commands, e-mail: [email protected] > > > > > > > > > > > > > > > > > > > > > --------------------------------------------------------------------- > > To unsubscribe, e-mail: [email protected] > > For additional commands, e-mail: [email protected] > > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [email protected] > For additional commands, e-mail: [email protected] > >
