https://issues.apache.org/bugzilla/show_bug.cgi?id=48971
--- Comment #5 from Konstantin Kolinko <knst.koli...@gmail.com> 2010-03-28 21:30:07 UTC --- Created an attachment (id=25203) --> (https://issues.apache.org/bugzilla/attachment.cgi?id=25203) bug48971_DBCP_reproducer.zip - IllegalStateException caused by stopped timer Any DBCP pool that has timeBetweenEvictionRunsMillis attribute set to a positive value will suffer from this issue. The class that creates the timer is org.apache.commons.pool.impl.EvictionTimer and is (after being renamed) in tomcat-dbcp.jar, which is in the Common class loader. It looks that the TimerThread created by the Timer will belong to the first web application that happens to access the pool. Forcibly stopping the timer creates an invalid state in the DBCP and the next web applications may fail to start. I am attaching configuration that reproduces this issue. To reproduce: 1. Unpack the zip archive, and place the provided files on top of the default configuration of Tomcat 6.0.26. It contains: 1) /data - Two sample HSQLDB databases (http://hsqldb.org/), "database" and "database2". These are identical and contain a single table with two rows of data - see the *.script files. 2) /lib - HSQLDB 1.8.1.2 jar. 3) /conf - server.xml that defines a database pool in GlobalResources. - tomcat-users.xml that contains a username and password for the manager application 4) /webapps - Two web applications, test1 and test2. These are nearly identical, with the following only difference between them (see META-INF/context.xml): - test1 uses connection pool defined in server.xml - test2 uses its own connection pool 5) /logs - Logs from my test run. 2. Copy jstl.jar and standard.jar from /webapps/examples/WEB-INF/lib/ of Tomcat into the /lib folder of Tomcat. 3. Start Tomcat 4. Go to http://localhost:8080/test1/ A test page should load and print two database rows. 5. Go to http://localhost:8080/manager/html/ and stop the test1 application. Note, that Tomcat stops TimerThread created by DBCP. 6. Go to http://localhost:8080/test2/ Expected result: The same output as for test1 before. Actual result: The page fails to load, displaying DataSource invalid: "java.lang.IllegalStateException: Timer already cancelled." It is not seen from the stack trace, but my understanding here is that that occurs because in Commons Pools, when a new pool is initialized, the GenericObjectPool#startEvictor(..) method creates a new Evictor and calls Timer.schedule(..) to schedule it, but the timer is already canceled. Other issues: 1) I suspect that when the pool defined in server.xml is initialized, the TCCL occurs to be equal to the classloader of the web application. I have not yet confirmed that, but that will be a separate bug (causing its own leaks) if it is the case. 2) HSQLDB creates its own "HSQLDB Timer" thread. That is not important, because DBCP issue I am talking about is independent of what database is used. If anyone is curious: that thread is created by the org.hsqldb.lib.HsqlTimer class. Regarding the feature of stopping TimerThreads: 1) I agree with Sylvain that it looks like that it would be better to have it disabled by default, but I would like to have a separate option to control enabling this feature. 2) I think that another strategy is possible here: to call Thread.setContextClassLoader(null) on the affected threads. That can have its consequences, but might be better than stopping the threads. Workaround: Do not set "timeBetweenEvictionRunsMillis" attribute on a pool. -- Configure bugmail: https://issues.apache.org/bugzilla/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are the assignee for the bug. --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org