views:

36

answers:

1

Hi,

I have a Spring based Wicket app.
There's a pooled datasource bean.
Now, when MySQL is dead, I get a default Wicket error page with a stacktrace.

I'd like to handle this situation and to only allow some pages to fully display (the static ones), and to show a custom error page for the others.

How should I efficiently implement this?

I know I could catch exceptions in the page's code, but this is kind of unreliable MySQL instance and it's down quite often :) Or, think of other kind of unreliable resource. Putting an if for each page seems inefficient. I'd like some list of pages that need the resource, and redirecting requests to it to a custom error page.

I was thinking about having some global boolean isResourceReady, and some thread which would start upon that error and periodically check for availability, and eventually allow the dynamic pages when the resource is back.

Thanks for tips.

Root cause:

java.net.ConnectException: Connection refused
at ... java.net stuff
... JDBC stuff
... Spring stuff
... DBCP and Pool stuff
... Hibernate stuff
at org.hibernate.ejb.QueryImpl.getSingleResult(QueryImpl.java:88)
at cz.oz.wicket.stack.dao.TestEntityDaoImpl$1.doInJpa(TestEntityDaoImpl.java:36)
at org.springframework.orm.jpa.JpaTemplate.execute(JpaTemplate.java:184)
at cz.oz.wicket.stack.dao.TestEntityDaoImpl.createSyntheticTestEntity(TestEntityDaoImpl.java:32)
at cz.oz.wicket.stack.pages.home.HomePage.<init>(HomePage.java:31)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.apache.wicket.session.DefaultPageFactory.createPage(DefaultPageFactory.java:188)
at org.apache.wicket.session.DefaultPageFactory.newPage(DefaultPageFactory.java:65)
at org.apache.wicket.request.target.component.BookmarkablePageRequestTarget.newPage(BookmarkablePageRequestTarget.java:298)
at org.apache.wicket.request.target.component.BookmarkablePageRequestTarget.getPage(BookmarkablePageRequestTarget.java:320)
at org.apache.wicket.request.target.component.BookmarkablePageRequestTarget.processEvents(BookmarkablePageRequestTarget.java:234)
at org.apache.wicket.request.AbstractRequestCycleProcessor.processEvents(AbstractRequestCycleProcessor.java:92)
at org.apache.wicket.RequestCycle.processEventsAndRespond(RequestCycle.java:1250)
at org.apache.wicket.RequestCycle.step(RequestCycle.java:1329)
at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1428)
at org.apache.wicket.RequestCycle.request(RequestCycle.java:545)
at org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:479)
at org.apache.wicket.protocol.http.WicketFilter.doFilter(WicketFilter.java:312)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:926)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:549)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:410)
at org.mo
+1  A: 

You might be best off using the normal error page handling in Wicket.

But if you want to anticipate the exception instead of reacting to it, this seems like a natural application of a ServletFilter. Particularly if you're already using the spring OpenSessionInViewFilter, you might subclass that and override the

protected Session getSession(SessionFactory sessionFactory) 

to detect that you've got no database connection and forward to a special page.

If you're doing it by a filter, the decision of whether to go to the error page or not might still have to be driven by some sort of global, but this might just be a list of your static pages that you maintain in your WebApplication object, which is already a singleton.

Don Roby