What is the ModificationWatcher?ModificationWatcher is a Wicket class that checks to see if resources have been modified and reloads them without restarting the servlet container (where possible). This is made possible by setting up a polling frequency in the init() method of the WebApplication class for your project. Unfortunately, Google App Engine does not allow the spawning of new threads (on which the ModificationWatcher class depends on), hence a work-around is necessary. First we need to look at the WicketApplication class, as shown in the example below:
- import org.apache.wicket.Application;
- import org.apache.wicket.protocol.http.HttpSessionStore;
- import org.apache.wicket.protocol.http.WebApplication;
- import org.apache.wicket.protocol.http.WebRequest;
- import org.apache.wicket.session.ISessionStore;
- import org.apache.wicket.util.lang.PackageName;
-
- public class WicketApplication extends WebApplication {
-
- @Override
- protected void init() {
- super.init();
-
- }
-
- protected WebRequest newWebRequest(HttpServletRequest servletRequest) {
- getResourceSettings().getResourceWatcher(true).start(
- getResourceSettings().getResourcePollFrequency());
- return super.newWebRequest(servletRequest);
- }
-
- @Override
- public String getConfigurationType() {
- return Application.DEVELOPMENT;
-
- }
-
- @Override
- protected ISessionStore newSessionStore() {
- return new HttpSessionStore(this);
-
- }
- }
The first 'hack' to getting Wicket working in GAE is to set the session store type for Wicket to HttpSessionStore, instead of using the SecondLevelCacheSessionStore as the latter directly refers to the file system and is not allowed in the app engine sandbox. This is done by overriding the newSessionStore() method [line 29 in the code extract shown above].
Now, back to the ModificationWatcher. If you want to completely disable it, you can set the poll frequency to null in the init method of your WebApplication class [this has been commented out in line 13 above]. However, if you are in development, this will mean that any changes to the source pages [in my experience its really been the HTML pages], you will have to restart your servlet container to pick-up the changes, which is not very efficient for development purposes. This work-around by-passes the polled watching for file changes and checks to see if the file has changed every time it is requested for. This is achieved by overriding the newWebRequest() method [see line 16 above]. This is fine for development purposes, and MUST be disabled for production, for obvious reasons.
And for this to work, you need a version of the ModificationWatcher class that does not spawn any threads. ModificationWatcher was declared a final class and hence cannot be extended, and so you need to override the Wicket provided version with one of your own. This is easily achieved by creating a similar package structure in your source code and creating the file : org.apache.wicket.util.watch.ModificationWatcher. The code for this class is as below:
All that has been done is that the Threading references have been taken out so no new threads are spawned and the check for the resources is done in the same thread as that the one that is servicing the user request. This is not the most elegant solution, but it works.
This hack is based on the following sources: