Hi,
I will try to give informations on what is done in javamelody and what
is done in spring, and I will give a jar for test.
When the filter of javamelody is initialized and if quartz classes are
present, javamelody add a listener on all quartz schedulers and in
particular on the default quartz scheduler:
http://code.google.com/p/javamelody/source/browse/trunk/javamelody-core/src/main/java/net/bull/javamelody/JobGlobalListener.java#46
This listener is used to display in javamelody the execution time, cpu
time and sql executions of each jobs.
The fact of getting the default quartz listener initializes it if
needed with the quartz.properties configuration or with the default
quartz configuration.
Most applications with quartz jobs use the default quartz scheduler
via StdSchedulerFactory.getDefaultScheduler().
Javamelody does not shutdown the quartz scheduler(s) when the webapp
is undeployed (or on server shutdown) because the destroy method of
the javamelody filter is perhaps not the right time to shutdown the
quartz schedulers and also because javamelody does not know if you
want to wait or not for jobs to complete before shutdown. So most
applications should call shutdown() on the quartz schedulers when the
webapp is undeployed (for example, in a
ServletContextListener.contextDestroyed method) otherwise the server
can't be shutdown : the quartz threads are not stopped and they are
not flagged as daemons which prevents the jvm to stop.
Until now all is good: quartz jobs in applications are executed and
the javamelody listener can monitor the jobs. Threads are stopped when
the application calls shutdown on the default scheduler or on all
schedulers.
And Spring comes. In fact, SchedulerFactoryBean in Spring does not use
the default quartz scheduler, it creates its own scheduler. And by
default, Spring does not want that the quartz scheduler is known by
quartz: Spring removes the scheduler from quartz just after its
creation, unless exposeSchedulerInRepository is set to true in
SchedulerFactoryBean. That's why exposeSchedulerInRepository should be
set to true in order for javamelody to display the jobs from Spring.
In the destroy method of SchedulerFactoryBean, the
scheduler.shutdown(waitForJobsToCompleteOnShutdown) is called in order
to stop the threads of the quartz scheduler and I suppose (without
having checked it) that this destroy is called via
org.springframework.web.context.ContextLoaderListener.contextDestroyed.
So I suppose that if the ContextLoaderListener is used in a
application, the quartz threads of the scheduler in
SchedulerFactoryBean are stopped.
But it seems that some other threads were started when javamelody
called StdSchedulerFactory.getDefaultScheduler(): those threads are
not stopped.
Those threads could certainly be stopped by the application with
StdSchedulerFactory.getDefaultScheduler().shutdown() or better with:
for (Scheduler scheduler :
SchedulerRepository.getInstance().lookupAll())
{ scheduler.shutdown(); }
[burkhard: if some quartz threads are not stopped by the
scheduler.shutdown() above, where these threads come from? Spring?]
In order that the applications using quartz via Spring
SchedulerFactoryBean do not have to call scheduler.shutdown() as above
to stop the threads, I have a proposal:
a javamelody parameter "quartz-default-listener-disabled" can be
added.
If this parameter has the value "true", javamelody would not call
StdSchedulerFactory.getDefaultScheduler() to add the listener, and so
the threads of the default quartz scheduler would not be started. The
only quartz threads will be started by SchedulerFactoryBean.
You can test that by using this jar I have just built:
http://javamelody.googlecode.com/files/javamelody-20101103.jar
and by adding the following for the javamelody filter in your web.xml:
<init-param>
<param-name>quartz-default-listener-disabled</param-name>
<param-value>true</param-value>
</init-param>
If this works for you, I will add that in the next release.
Happy hacking !
Emeric