I have made a few tweaks to the connection pool leak detection.
... datasource.h2.maxConnections=25 datasource.h2.capturestacktrace=true
Put the capturestacktrace = true parameter ... and then the Ebean DataSource will get the stack element array when we get a connection.
If the pool runs out of connections it will reset itself (or you can call the reset manually) ... and at that point busy connections will be checked to see if they are possible connection pools.
Also when the connection pool is shutdown the information on the busy connections are also dumped.
It is logged and also send to sys err. It is sent to sys err because the loggers stop working early in a JVM shutdown.
The logged information is:
INFO: DataSourcePool [h2] grow pool; busy[24] size[24] max[25]17/03/2010 05:17:48 com.avaje.ebeaninternal.server.lib.sql.DataSourcePool resetINFO: Reseting DataSourcePool [h2]17/03/2010 05:17:48 com.avaje.ebeaninternal.server.lib.sql.DataSourcePool resetINFO: Busy Connections:name[h2.1] startTime[1268803068504] stmt[null] createdBy[com.avaje.tests.query.TestPagingListLoop.createLeak(TestPagingListLoop.java:39)]name[h2.2] startTime[1268803068506] stmt[null] createdBy[com.avaje.tests.query.TestPagingListLoop.createLeak(TestPagingListLoop.java:39)]
example:
17/03/2010 05:17:48 com.avaje.ebeaninternal.server.lib.sql.DataSourcePool closeBusyConnectionsWARNING: DataSourcePool closing leaked connection? name[h2.1] lastUsed[Wed Mar 17 05:17:48 GMT 2010] createdBy[com.avaje.tests.query.TestPagingListLoop.createLeak(TestPagingListLoop.java:39)] lastStmt[null]17/03/2010 05:17:48 com.avaje.ebeaninternal.server.lib.sql.DataSourcePool logStackElementWARNING: Possible Leaked Connection: name[h2.1] stackTrace: [com.avaje.tests.query.TestPagingListLoop.createLeak(TestPagingListLoop.java:39), com.avaje.tests.query.TestPagingListLoop.test(TestPagingListLoop.java:20), sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method), sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39), sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)]Possible Leaked Connection: name[h2.1] stackTrace: [com.avaje.tests.query.TestPagingListLoop.createLeak(TestPagingListLoop.java:39), com.avaje.tests.query.TestPagingListLoop.test(TestPagingListLoop.java:20), sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method), sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39), sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)]17/03/2010 05:17:48 com.avaje.ebeaninternal.server.lib.sql.PooledConnection closeConnectionFully ...
So there can be a lot dumped out.
So the stack trace points out where the connection was created (and never closed).
In the example above I have a connection pool leak in:
com.avaje.tests.query.TestPagingListLoop.createLeak(TestPagingListLoop.java:39)
Fixed in HEAD.