Re: Q: how to obtain notification when a WebApp is unloaded/reloaded?

2010-04-25 Thread Godmar Back
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?

2010-04-22 Thread Godmar Back
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?

2010-04-14 Thread Godmar Back
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?

2010-04-14 Thread Godmar Back
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?

2010-04-13 Thread Godmar Back
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