Details
Description
When undeploying a Wicket web application from Tomcat by removing the war file from the deploy sub-directory (in other words, a hot undeploy), a FileNotFoundException prevents Wicket from shutting down properly.
The exception is caused when Wicket's internalDestroy() method needs classes that have not yet been loaded and the class loader attempts to load them from the (now) undeployed war file.
A work around is to preload the classes that Wicket will need during the destroy phase. I was able to resolve the issue using these class loader statements in the init() method of my Wicket WebApplication implementation:
getClass().getClassLoader().loadClass("org.apache.wicket.ApplicationListenerCollection$2"); getClass().getClassLoader().loadClass("org.apache.wicket.core.util.lang.PropertyResolver"); getClass().getClassLoader().loadClass("org.apache.wicket.core.util.lang.PropertyResolver$IPropertyLocator");
The internalDestroy() method is called from org.apache.wicket.protocol.http.WicketFilter.destroy() in a 'try...finally' block that does not log the Exception. Wicket discourages overwriting this method but doing so allows the stack trace to be logged, as follows:
@Override public void internalDestroy() { log.info("internalDestroy: ENTER"); try { super.internalDestroy(); } catch ( Exception ex ) { ex.printStackTrace(); throw ex; } log.info("internalDestroy: EXIT"); }
Note: For additional troubleshooting, Tomcat provides a 'find leaks' feature on its 'Application Manager' page that reports issues when Wicket fails to undeploy properly.