I can kind of see what is going on, the YourApplication class is loaded using a different classloader then the wicket jar. and tomcat cleans it up. fair enough. but, YourApplication class extends Application which is inside the jar, so tomcat should not be cleaning it up...makes no sense. How can the entire jar be gone if one of the classes that was loaded from it is still being used. It may be an optimization they do but its may be backfiring in this particular case. You may have to use your jar protector as a permanent workaround.
-igor On Sun, Mar 21, 2010 at 2:57 AM, Alexandros Karypidis <akary...@yahoo.gr> wrote: > Ok, I've pinpointed the underlying cause. Indeed, the file is simply removed > before the destroy() method has a chance to clean up. I verified this by > using this ugly hack: > > 1. Adding a field: > private InputStream wicketJarProtector; > > 2. In WicketFilter.init() I open the wicket jar to "protect" it from > deletion: > wicketJarProtector = > filterConfig.getServletContext().getResourceAsStream("/WEB-INF/lib/wicket.jar"); > > 3. In WicketFilter.destroy() I close the file handle: > wicketJarProtector.close(); > > This prevents the file from being deleted, undeployment completes > successfully. > > I'm not sure how to "properly" fix this... Any ideas? > > On 21/3/2010 11:38 πμ, Alexandros Karypidis wrote: >> >> Well, if I force the class to be loaded early this way, destroy() simply >> fails a little bit further down, when trying to load a nested class. >> >> java.lang.NoClassDefFoundError: >> org/apache/wicket/util/lang/PropertyResolver$IClassCache >> at org.apache.wicket.Application.internalDestroy(Application.java:952) >> at >> org.apache.wicket.protocol.http.WebApplication.internalDestroy(WebApplication.java:527) >> at >> org.apache.wicket.protocol.http.WicketFilter.destroy(WicketFilter.java:180) >> ... >> >> I could keep going by adding references to such classes until every class >> needed to complete destroy() is pre-loaded, but the fact is that for some >> reason, there is no more access to "wicket.jar" in "WEB-INF/lib". I added >> debugged through the code and the weird thing is that it's the same >> class-loader AND the same thread (JBoss' [HDScanner] thread). So it should >> be able to load these classes. A look at the bottom of the stack trace >> reveals this (notice that there is a "DelegatingHandler" to "wicket.jar" and >> all packages for wicket are listed; so it's as if "wicket.jar" is simply no >> longer in its place (i.e. the OS removes it before the class loader has a >> chance to load the classes needed for destroy): >> >> Caused by: java.lang.ClassNotFoundException: >> org.apache.wicket.util.lang.PropertyResolver$IClassCache from >> baseclassloa...@10496f0{vfsclassloaderpolicy@517ead{name=vfsfile:/F:/ade_ws/.metadata/.plugins/org.jboss.ide.eclipse.as.core/JBoss_5.1_(default)/deploy/wicket-cl-test.war/ >> domain=classloaderdom...@1e351a2{name=vfsfile:/F:/ade_ws/.metadata/.plugins/org.jboss.ide.eclipse.as.core/JBoss_5.1_(default)/deploy/wicket-cl-test.war/ >> parentPolicy=AFTER_BUT_JAVA_BEFORE >> parent=classloaderdom...@4d41e2{defaultdomain}} roots=[.........., >> delegatinghand...@8305721[path=wicket-cl-test.war/WEB-INF/lib/wicket.jar >> context=file:/F:/ade_ws/.metadata/.plugins/org.jboss.ide.eclipse.as.core/JBoss_5.1_(default)/deploy/ >> real=file:/F:/ade_ws/.metadata/.plugins/org.jboss.ide.eclipse.as.core/JBoss_5.1_(default)/deploy/wicket-cl-test.war/WEB-INF/lib/wicket.jar]] >> delegates=null exported=[, org.apache.wicket.util.diff.myers, >> org.apache.wicket.markup.transformer, >> org.apache.wicket.authorization.strategies.page, >> org.apache.wicket.ajax.form, org.apache.log4j, >> org.apache.wicket.util.convert, org.apache.wicket.util.resource, >> org.apache.wicket.authorization.strategies, org.apache.log4j.lf5.config, >> org.apache.log4j.spi, org.apache.wicket.protocol.http.servlet, >> org.apache.wicket.markup.resolver, >> org.apache.wicket.request.target.resource, >> org.apache.wicket.util.parse.metapattern, ................................] >> <IMPORT-ALL>NON_EMPTY}} >> at >> org.jboss.classloader.spi.base.BaseClassLoader.loadClass(BaseClassLoader.java:448) >> at java.lang.ClassLoader.loadClass(ClassLoader.java:248) >> ... 72 more >> >> >> On 20/3/2010 10:25 μμ, Igor Vaynberg wrote: >>> >>> interesting, wonder why the class would be unloaded *before* the >>> application classloader. >>> >>> try this, add a field private PropertyClassResolver resolver=null; to >>> your application subclass, see if the field is enough to stop the >>> class from unloading. >>> >>> -igor >>> >>> On Sat, Mar 20, 2010 at 9:06 AM, Alexandros Karypidis<akary...@yahoo.gr> >>> wrote: >>>> >>>> Hi, >>>> >>>> I'm having problems with deployment/undeployment of Wicket apps on >>>> Tomcat >>>> (and also JBoss, though I think it's related to the fact that it embeds >>>> Tomcat). Basically, in both cases undeployment comes back with an >>>> Exception, >>>> leaving the server in a "dirty" state and I have to restart the server >>>> every >>>> time. This has been mentioned in both the user and developer lists, but >>>> with >>>> no reply: >>>> >>>> >>>> http://old.nabble.com/java.lang.NoClassDefFoundError:-org-apache-wicket-util-lang-PropertyResolver-tc26191924.html >>>> http://old.nabble.com/Weird-error-on-shutdown...-td18907685.html >>>> >>>> The problem manifests only when deploying EXPLODED wars (with a single >>>> packaged WAR file, the problem goes away). It can be easily reproduced >>>> as >>>> follows: >>>> >>>> 1) Create an instance of the quickstart archetype >>>> (http://wicket.apache.org/quickstart.html). Let's say you used the >>>> default >>>> values so the artifact id is "myproject" from here on. Use the latest >>>> 1.4.7 >>>> version of Wicket (though I've tried with all previous versions up to >>>> 1.4.4 >>>> and the result is the same; the reference above uses version 1.4-m2, so >>>> it >>>> must be surprisingly old). >>>> 2) Create an EXPLODED web archive (war) with "mvn war:exploded" >>>> 3) Move the exploded war folder (myproject-1.0-SNAPSHOT) to the >>>> deployment >>>> folder ("server/xxx/deploy" for JBoss or "webapps") >>>> 4) Undeploy by moving the exploded war folder (myproject-1.0-SNAPSHOT), >>>> OUT >>>> of the deployment folder >>>> >>>> You will get a stack trace that basically ends up in a ClassNotFound >>>> exception when the Wicket filter is cleaning up: >>>> >>>> java.lang.NoClassDefFoundError: >>>> org/apache/wicket/util/lang/PropertyResolver >>>> at >>>> org.apache.wicket.Application.internalDestroy(Application.java:952) >>>> at >>>> >>>> org.apache.wicket.protocol.http.WebApplication.internalDestroy(WebApplication.java:527) >>>> at >>>> >>>> org.apache.wicket.protocol.http.WicketFilter.destroy(WicketFilter.java:179) >>>> at >>>> >>>> org.apache.catalina.core.ApplicationFilterConfig.release(ApplicationFilterConfig.java:267) >>>> .... >>>> >>>> This is a huge annoyance, because re-deployment of the application does >>>> not >>>> work; if you try to deploy it again, JBoss fails with: >>>> >>>> org.jboss.deployers.spi.DeploymentException: Web mapping already exists >>>> for >>>> deployment URL >>>> >>>> file:/F:/ade_ws/.metadata/.plugins/org.jboss.ide.eclipse.as.core/JBoss_5.1_(default)/deploy/myproject-1.0-SNAPSHOT/ >>>> at >>>> >>>> org.jboss.web.tomcat.service.deployers.TomcatDeployment.performDeployInternal(TomcatDeployment.java:187) >>>> >>>> Basically, you must restart the entire JBoss server. In a production >>>> environment it means you can't upgrade your wicket applications without >>>> affecting other applications (though you can get away if you don't use >>>> an >>>> exploded WAR folder). In a developer environment it's totally >>>> counter-productive: you need the exploded format and restaring JBoss >>>> every >>>> time is quite irritating. The Eclipse WTP adapter runs in "exploded" >>>> mode >>>> which basically makes working with Eclipse a nightmare. >>>> >>>> I am using JDK1.6 (I use 1.6.0_18) and either JBoss5.1 or Tomcat 6.0.26 >>>> (or >>>> 6.0.18 or 5.5.28 which I also tried). My system is running Windows 7 and >>>> NTFS (it may be relevant to the way the file-system handles moving >>>> folders). >>>> >>>> Last notes: >>>> >>>> 1) I had a look at the code. It seems that Wicket tries to use weak >>>> references to facilitate a thorough clean-up of the JVM by garbage >>>> collection after the application is undeployed. This may be related, as >>>> it >>>> appears to me as if the class loader used by the application is no >>>> longer >>>> available during clean-up. I think there's some class-loading magic >>>> going >>>> on, probably the thread's context class loader is being switched, which >>>> ends >>>> up in the destroy() method not having access to wicket. >>>> >>>> 2) Jetty does not seem to have any problems, so it must be something in >>>> the >>>> way Tomcat works. >>>> >>>> 3) The complete stack trace in my case (Win7, JDK1.6.0_18-win32, >>>> JBoss5.1, >>>> Wicket1.4.7) is: >>>> java.lang.NoClassDefFoundError: >>>> org/apache/wicket/util/lang/PropertyResolver >>>> at >>>> org.apache.wicket.Application.internalDestroy(Application.java:952) >>>> at >>>> >>>> org.apache.wicket.protocol.http.WebApplication.internalDestroy(WebApplication.java:527) >>>> at >>>> >>>> org.apache.wicket.protocol.http.WicketFilter.destroy(WicketFilter.java:179) >>>> at >>>> >>>> org.apache.catalina.core.ApplicationFilterConfig.release(ApplicationFilterConfig.java:267) >>>> at >>>> >>>> org.apache.catalina.core.StandardContext.filterStop(StandardContext.java:3818) >>>> at >>>> org.apache.catalina.core.StandardContext.stop(StandardContext.java:4605) >>>> at >>>> org.apache.catalina.core.ContainerBase.destroy(ContainerBase.java:1175) >>>> at >>>> >>>> org.apache.catalina.core.StandardContext.destroy(StandardContext.java:4705) >>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) >>>> at >>>> >>>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) >>>> at >>>> >>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) >>>> at java.lang.reflect.Method.invoke(Method.java:597) >>>> at >>>> >>>> org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:297) >>>> at >>>> org.jboss.mx.server.RawDynamicInvoker.invoke(RawDynamicInvoker.java:164) >>>> at >>>> org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:668) >>>> at >>>> >>>> org.jboss.web.tomcat.service.deployers.TomcatDeployment.performUndeployInternal(TomcatDeployment.java:596) >>>> at >>>> >>>> org.jboss.web.tomcat.service.deployers.TomcatDeployment.performUndeploy(TomcatDeployment.java:570) >>>> at >>>> >>>> org.jboss.web.deployers.AbstractWarDeployment.stop(AbstractWarDeployment.java:480) >>>> at org.jboss.web.deployers.WebModule.stopModule(WebModule.java:133) >>>> at org.jboss.web.deployers.WebModule.stop(WebModule.java:102) >>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) >>>> at >>>> >>>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) >>>> at >>>> >>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) >>>> at java.lang.reflect.Method.invoke(Method.java:597) >>>> at >>>> >>>> org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:157) >>>> at org.jboss.mx.server.Invocation.dispatch(Invocation.java:96) >>>> at org.jboss.mx.server.Invocation.invoke(Invocation.java:88) >>>> at >>>> >>>> org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264) >>>> at >>>> org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:668) >>>> at >>>> >>>> org.jboss.system.microcontainer.ServiceProxy.invoke(ServiceProxy.java:206) >>>> at $Proxy38.stop(Unknown Source) >>>> at >>>> >>>> org.jboss.system.microcontainer.StartStopLifecycleAction.uninstallAction(StartStopLifecycleAction.java:56) >>>> at >>>> >>>> org.jboss.system.microcontainer.StartStopLifecycleAction.uninstallAction(StartStopLifecycleAction.java:37) >>>> at >>>> >>>> org.jboss.dependency.plugins.action.SimpleControllerContextAction.simpleUninstallAction(SimpleControllerContextAction.java:79) >>>> at >>>> >>>> org.jboss.dependency.plugins.action.AccessControllerContextAction.uninstall(AccessControllerContextAction.java:131) >>>> at >>>> >>>> org.jboss.dependency.plugins.AbstractControllerContextActions.uninstall(AbstractControllerContextActions.java:58) >>>> at >>>> >>>> org.jboss.dependency.plugins.AbstractControllerContext.uninstall(AbstractControllerContext.java:354) >>>> at >>>> >>>> org.jboss.dependency.plugins.AbstractController.uninstall(AbstractController.java:1664) >>>> at >>>> >>>> org.jboss.dependency.plugins.AbstractController.uninstallContext(AbstractController.java:1275) >>>> at >>>> >>>> org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:827) >>>> at >>>> >>>> org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:553) >>>> at >>>> org.jboss.system.ServiceController.doChange(ServiceController.java:688) >>>> at >>>> org.jboss.system.ServiceController.stop(ServiceController.java:510) >>>> at >>>> >>>> org.jboss.system.deployers.ServiceDeployer.stop(ServiceDeployer.java:170) >>>> at >>>> >>>> org.jboss.system.deployers.ServiceDeployer.undeploy(ServiceDeployer.java:150) >>>> at >>>> >>>> org.jboss.system.deployers.ServiceDeployer.undeploy(ServiceDeployer.java:46) >>>> at >>>> >>>> org.jboss.deployers.spi.deployer.helpers.AbstractSimpleRealDeployer.internalUndeploy(AbstractSimpleRealDeployer.java:69) >>>> at >>>> >>>> org.jboss.deployers.spi.deployer.helpers.AbstractRealDeployer.undeploy(AbstractRealDeployer.java:112) >>>> at >>>> >>>> org.jboss.deployers.plugins.deployers.DeployerWrapper.undeploy(DeployerWrapper.java:196) >>>> at >>>> >>>> org.jboss.deployers.plugins.deployers.DeployersImpl.doUndeploy(DeployersImpl.java:1469) >>>> at >>>> >>>> org.jboss.deployers.plugins.deployers.DeployersImpl.doUninstallParentLast(DeployersImpl.java:1376) >>>> at >>>> >>>> org.jboss.deployers.plugins.deployers.DeployersImpl.doUninstallParentLast(DeployersImpl.java:1369) >>>> at >>>> >>>> org.jboss.deployers.plugins.deployers.DeployersImpl.uninstall(DeployersImpl.java:1331) >>>> at >>>> >>>> org.jboss.dependency.plugins.AbstractControllerContext.uninstall(AbstractControllerContext.java:354) >>>> at >>>> >>>> org.jboss.dependency.plugins.AbstractController.uninstall(AbstractController.java:1664) >>>> at >>>> >>>> org.jboss.dependency.plugins.AbstractController.uninstallContext(AbstractController.java:1275) >>>> at >>>> >>>> org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:827) >>>> at >>>> >>>> org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:553) >>>> at >>>> >>>> org.jboss.deployers.plugins.deployers.DeployersImpl.process(DeployersImpl.java:694) >>>> at >>>> >>>> org.jboss.deployers.plugins.main.MainDeployerImpl.process(MainDeployerImpl.java:679) >>>> at >>>> >>>> org.jboss.system.server.profileservice.repository.MainDeployerAdapter.process(MainDeployerAdapter.java:117) >>>> at >>>> >>>> org.jboss.system.server.profileservice.hotdeploy.HDScanner.scan(HDScanner.java:362) >>>> at >>>> >>>> org.jboss.system.server.profileservice.hotdeploy.HDScanner.run(HDScanner.java:255) >>>> at >>>> java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441) >>>> at >>>> >>>> java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317) >>>> at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150) >>>> at >>>> >>>> java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98) >>>> at >>>> >>>> java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:181) >>>> at >>>> >>>> java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:205) >>>> at >>>> >>>> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) >>>> at >>>> >>>> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) >>>> at java.lang.Thread.run(Thread.java:619) >>>> >>>> >>>> --------------------------------------------------------------------- >>>> To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org >>>> For additional commands, e-mail: users-h...@wicket.apache.org >>>> >>>> >>> --------------------------------------------------------------------- >>> To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org >>> For additional commands, e-mail: users-h...@wicket.apache.org >>> >> >> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org >> For additional commands, e-mail: users-h...@wicket.apache.org > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org > For additional commands, e-mail: users-h...@wicket.apache.org > > --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org For additional commands, e-mail: users-h...@wicket.apache.org