Re: Q: how to obtain notification when a WebApp is unloaded/reloaded?
On Sun, Apr 25, 2010 at 12:29 PM, users-digest-h...@tomcat.apache.orgwrote: -- Forwarded message -- From: Christopher Schultz ch...@christopherschultz.net To: Tomcat Users List users@tomcat.apache.org Date: Fri, 23 Apr 2010 12:29:26 -0400 Subject: Re: Q: how to obtain notification when a WebApp is unloaded/reloaded? -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Godmar, On 4/14/2010 10:20 AM, Godmar Back wrote: I have added a ServletContextListener, but it is very much a solution I strongly dislike. The reason is that my application is layered on top of another application (ZK), and I don't really want to touch web.xml. 'web.xml' describes how ZK is configured to run inside Tomcat or another J2EE server. My applications runs on top of ZK, and having to go and made changes to the underlying deployment descriptor violates basic principles of layering. It also creates a maintenance problem (unless an application can have multiple .xml files that are combined to form a deployment descriptor). Whenever ZK is updated, a new version of web.xml will be installed, and I would then have to merge my listener declaration into the new file. What is your deployment procedure? We use ant for our deployments and it's trivial to use the xslt task to mutate XML files such as web.xml. If you do this, you can set up your deployment process once and not worry about it, even if ZK publishes an update. My deployment procedure is extremely simple - I do a CVS checkout into the webapps dir. Immediate deployment (without having to bother creating war files, etc. etc.) To reply to an earlier comment that I should use a separate web.xml - I don't see how this would be possible. listener-classorg.libx.editionbuilder.GCHelper$ShutdownListener/listener-class /listener I think the class needs to be a top level class with a parameter free constructor. I'm not sure if it needs to be top-level, but it will at least need to be static. Can you post the code for GCHelper$ShutdownListener? Just to be clear - there is no problem with GCHelper$ShutdownListener. Its methods are invoked on application shutdown the first time. It is a static class and it doesn't need to be top-level. The problem arises when the web application is recompiled. Recompilation works in two steps. First, I remove all files in the classes directory (/bin/rm -rf WEB-INF/classes), then I run javac to recompile the classes from a script. Once Tomcat sees that the files have been removed, it'll declare the web application dead and stops reloading it. This is very unfortunate. A work-around I'm trying now is as follows: I don't delete the .class files when recompiling. This way, Tomcat will never see them gone. Of course, this will leave stale .class files around when classes are renamed. However, these can be handled by periodically shutting down Tomcat and cleaning the WEB-INF/classes directory. One of my team members uses Eclipse to develop - I assume it will cause the same problems should Eclipse clean the class directory before recompiling, as it can be configured to do. - Godmar
Re: Q: how to obtain notification when a WebApp is unloaded/reloaded?
Following up on an earlier conversation about how to obtain notification when a WebApp is unloaded/reloaded [1], I was told that registering a ServletContextListener is the only possibility (that is, there is no runtime API.) However, registering a ServletContextListener doesn't work and leads to me being unable to start the web application. To recap: I have an application with context reloadable=true. I continuously recompile this application during development. The application starts a worker thread I need to shut down when a newly compiled version of the application is loaded (that is, when new versions of the .class files show up in the WEB-INF/classes directory. Right now, I'm getting messages that the listener class is missing (it isn't - it's just a new .class file after recompilation.) Apr 22, 2010 10:31:25 PM org.apache.catalina.loader.WebappClassLoader modified SEVERE: Resource '/WEB-INF/classes/org/libx/editionbuilder/GCHelper$ShutdownListener.class' is missing Apr 22, 2010 10:31:25 PM org.apache.catalina.core.StandardContext reload INFO: Reloading this Context has started Apr 22, 2010 10:31:25 PM org.apache.catalina.core.StandardContext start SEVERE: Error listenerStart Apr 22, 2010 10:31:25 PM org.apache.catalina.core.StandardContext start SEVERE: Context [/gbed] startup failed due to previous errors My web.xml contains: listener listener-classorg.libx.editionbuilder.GCHelper$ShutdownListener/listener-class /listener So - what is the correct way to register a listener that is executed when an application is reloaded due to a recompilation? Does Tomcat get confused when the listener class itself is part of the to-be-reloaded web application? Thanks. - Godmar [1] See http://mail-archives.apache.org/mod_mbox/tomcat-users/201004.mbox/%3cu2s719dced31004132122oc656c456ya25e1a4ba4d4a...@mail.gmail.com%3e and the messages in that thread. -- Forwarded message -- From: Godmar Back god...@gmail.com Date: Wed, Apr 14, 2010 at 10:20 AM Subject: Re: Q: how to obtain notification when a WebApp is unloaded/reloaded? To: Tomcat Users List users@tomcat.apache.org On Wed, Apr 14, 2010 at 10:12 AM, Pid p...@pidster.com wrote: For instance, if you look at http://java.sun.com/products/servlet/2.3/javadoc/javax/servlet/ServletContextListener.html it says: To recieve (sic) notification events, the implementation class must be configured in the deployment descriptor for the web application. Web applications are largely configured by the web.xml file in app/WEB-INF. Servlets, listeners etc are all configured in it. Thank you for your confirmation. I thought I was going nuts, after having waded through various *Facade classes, hoping to find an API method I could call at runtime. I have added a ServletContextListener, but it is very much a solution I strongly dislike. The reason is that my application is layered on top of another application (ZK), and I don't really want to touch web.xml. 'web.xml' describes how ZK is configured to run inside Tomcat or another J2EE server. My applications runs on top of ZK, and having to go and made changes to the underlying deployment descriptor violates basic principles of layering. It also creates a maintenance problem (unless an application can have multiple .xml files that are combined to form a deployment descriptor). Whenever ZK is updated, a new version of web.xml will be installed, and I would then have to merge my listener declaration into the new file. Just out of curiosity, what is the rationale for the (apparently deliberate) lack of an runtime API? - Godmar
Re: Q: how to obtain notification when a WebApp is unloaded/reloaded?
On Wed, Apr 14, 2010 at 3:17 AM, Pid p...@pidster.com wrote: In my web application, I'm using the 'reloadable='true'' attribute to Context to reload the application automatically when a .class or jar files changes. To avoid a quickly accumulating memory leak, I need to shut down a service thread my application has started when the web application is reloaded. What API function can be used to notify my application that it is about to be shut down, so that the thread in question can exit? First, is there a standard API that would work also in other J2EE containers besides Tomcat? As Bob suggested, ServletContextListener is the way forwards. Thank you for your replies. I did see ServletContextListener (as well as LifeCycleListener, etc. etc.). What I couldn't find out is how to obtain an instance of the object that would support an 'addServletContextListener' method. For instance, if you look at http://java.sun.com/products/servlet/2.3/javadoc/javax/servlet/ServletContextListener.htmlit says: To recieve (sic) notification events, the implementation class must be configured in the deployment descriptor for the web application. This doesn't sound like an API to me, it sounds like a configuration option, so it doesn't answer my question. Is it true that there is, basically, no API a web application can call at runtime to add such listeners? The most likely candidate to which to add a ServletContextListener would be a ServletContext, but it doesn't appear to support an 'addListener' method, unless I'm overlooking it: http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/ServletContext.html Second, is there a custom API in Tomcat? Actually yes, but as you might imagine, there are restrictions. http://tomcat.apache.org/tomcat-6.0-doc/config/context.html#LifecycleListeners I saw that too, but again, it doesn't answer my problem. On the page you quote it says: The class name you specify must implement the org.apache.catalina.LifecycleListener interface, and the class must be packaged in a jar and placed in the $CATALINA_HOME/lib directory. I am interested in a solution that does not require access to the $CATALINA_HOME/lib directory. This directory is accessible only to the Tomcat administrator, and I would like my web app - if possible - to be deployed even in scenarios where the Tomcat configuration cannot be changed. And lastly, this solution would not work because the LifecycleListener itself would not be reloaded, since (to my knowledge) jar files in $CATALINA_HOME/lib aren't reloaded. I'm really interested in a solution that would be contained inside the web application (i.e., first or second above) and that would not require changes to the server configuration, so that it would work in hosted environments where I do not control the Tomcat configuration. I'm using the latest 6.0 release (6.0.20). 6.0.26? 6.0.24, actually. Thank you for your insights. - Godmar
Re: Q: how to obtain notification when a WebApp is unloaded/reloaded?
On Wed, Apr 14, 2010 at 10:12 AM, Pid p...@pidster.com wrote: For instance, if you look at http://java.sun.com/products/servlet/2.3/javadoc/javax/servlet/ServletContextListener.html it says: To recieve (sic) notification events, the implementation class must be configured in the deployment descriptor for the web application. Web applications are largely configured by the web.xml file in app/WEB-INF. Servlets, listeners etc are all configured in it. Thank you for your confirmation. I thought I was going nuts, after having waded through various *Facade classes, hoping to find an API method I could call at runtime. I have added a ServletContextListener, but it is very much a solution I strongly dislike. The reason is that my application is layered on top of another application (ZK), and I don't really want to touch web.xml. 'web.xml' describes how ZK is configured to run inside Tomcat or another J2EE server. My applications runs on top of ZK, and having to go and made changes to the underlying deployment descriptor violates basic principles of layering. It also creates a maintenance problem (unless an application can have multiple .xml files that are combined to form a deployment descriptor). Whenever ZK is updated, a new version of web.xml will be installed, and I would then have to merge my listener declaration into the new file. Just out of curiosity, what is the rationale for the (apparently deliberate) lack of an runtime API? - Godmar
Q: how to obtain notification when a WebApp is unloaded/reloaded?
Hi, I have a simple question I was unable to find an answer to even after 2 hours of reading documentation, APIs, and (partly) Tomcat source code. In my web application, I'm using the 'reloadable='true'' attribute to Context to reload the application automatically when a .class or jar files changes. To avoid a quickly accumulating memory leak, I need to shut down a service thread my application has started when the web application is reloaded. What API function can be used to notify my application that it is about to be shut down, so that the thread in question can exit? First, is there a standard API that would work also in other J2EE containers besides Tomcat? Second, is there a custom API in Tomcat? Third, if there is no API that a web application could use by itself, is it possible to achieve my goal by writing a custom thread manager that is loaded outside the specific web application? If so, are there examples of how to add such a class to the configuration? I'm really interested in a solution that would be contained inside the web application (i.e., first or second above) and that would not require changes to the server configuration, so that it would work in hosted environments where I do not control the Tomcat configuration. I'm using the latest 6.0 release (6.0.20). Thanks. - Godmar