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

Reply via email to