Avoid a classloader leak through a dangling statement cancel timer thread.

When the driver class was loaded, it started a Timer thread that was used
to cancel statements on timeout. This timer thread was never stopped.

When the class is loaded in containerized environment (web container,
ee container, ...) this might lead to eventual permgen depletion when the
deployment with the driver is merely reloaded (which may involve reloading
the classes of the deployment) repeatedly.

The timer thread holds on to the protection domain of the code that created
it and that protection domain holds on to the classloader that is used to
load the classes. Through this chain of references, the dangling threads
cause the classloader of the "previous" deployments to never be GC'ed and
their classes unloaded.

The fix is to have the cancel timer thread per-connection and tear it down
when closing the connection.

Note that exactly the same issue existed in MySQL JDBC driver where it was
fixed in 2009:
http://bugs.mysql.com/bug.php?id=36565
Yes, I did see the problem, wanted to verify  that checking for a null
would fix it?

Dave Cramer

On 1 October 2014 12:55, Sehrope Sarkuni <notifications@github.com> wrote:

> In org/postgresql/jdbc2/AbstractJdbc2Connection.java:
>
> > @@ -670,6 +672,7 @@ private void initObjectTypes(Properties info) throws SQLException
> >       */
> >      public void close()
> >      {
> > +        cancelTimer.cancel();
>
> The NPE is happening because the timer is lazy initialized when a timer
> task is added via addTimerTask(...). If no task is added, for example
> just open a connection then close it, it'll still be null when
> cancelTimer.cancel() is called on line 675.
>
> —
> Reply to this email directly or view it on GitHub
> <https://github.com/pgjdbc/pgjdbc/pull/188/files#r18291598>.
>