tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Christopher Schultz <ch...@christopherschultz.net>
Subject Re: About ContainerBackgroundProcessor thread
Date Tue, 28 Sep 2010 19:16:37 GMT
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Juan,

On 9/27/2010 8:32 AM, jmoratilla@dit.upm.es wrote:
> I have developed an application which instanciates a singleton class in
> the init method of a servlet. This servlet is defined in the web.xml with
> the <load-on-startup>1</load-on-startup> tag. This singleton class start
a
> Thread which notifies the singleton class when a configuration file has
> changed.

Wow. You're broken 4 of my all-time servlet programming rules in a
single paragraph:

1. Don't use servlets when you should use a ContextListener
2. Don't use load-on-startup (really a corollary of #1)
3. Don't use instance-level data in a servlet
4. Don't start threads from a servlet

Not everyone may agree with my "rules", but they've kept my apps stable.

> The thread checks if the file has changed periodically. If
> changed, it notifies the singleton.

Interesting.

> If I put this configuration file in a different directory than the one
> where the application is deployed, the application work as expected.
> 
> If I put the configuration file in the WEB-INF/classes directory the
> thread notifies the singleton that the file has changed, that's OK. But
> what is my suprise that, the init method of the servlet is executed again
> by a thread named [ContainerBackgroundProcessor[StandardEngine[Catalina]]]

As you have discovered, Tomcat is reloading the servlet context based on
the changed configuration file. Which file are you monitoring? Tomcat
will automatically reload webapps when certain files change, unless you
have set reloadable="false" in your Tomcat deployment descriptor.

As others have said, if you want to re-initialize some data, you
probably want to disable context reloading (reloadable="false") and then
get your code to re-initialize whatever component uses that
configuration file.

You will not be able to "reload" the servlet. Instead, you probably want
to re-read the configuration file and take appropriate action.

If you have your servlet like this:

public class MyServlet extends HttpServlet {

  private Thread _watcher = ...;

  public void init(...) {
     // read config file and configure some component
  }
}

Perhaps you can simply change this to:

public class MyServlet extends HttpServlet {

  private Thread _watcher = ...;

  public void init(...) {
    configureComponent("config.file");
  }

  public void configureComponent(String filename) {
     // read config file and configure some component
  }
}

Now, your thread can call configureComponent directly: there's no need
to actually reload the servlet. I also don't see the utility in using a
singleton: if you have a single thread doing the update checking, it's
unlikely that there will be contention of any resources. If you are
concerned (or just want to be careful -- always a good idea), simpyl
synchronize the method that does the check.

If you're using a reasonably recent version of Java, you ought to be
able to simply fire-off a Timer that calls a method on your class --
say, checkForConfigurationUpdate -- which performs the check and then
calls the configureComponent method.

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkyiPxUACgkQ9CaO5/Lv0PDs/wCeNraoSFOEcFDLa+g0HoUdhw8f
fAsAnjhoXrnmcVrK2pH9fSk4src93bd0
=0DHn
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Mime
View raw message