postgresql-jdbc.git / summary / log / commit / refs
commit 0bef49279d0c4d5bbb58e4ced79eff1f6d16d4c6
Author: Kris Jurka <books@ejurka.com>
Date: Wed Nov 23 19:24:55 2005 +0000
Add a URL parameter to enable logging of Connections which are
finalized, but not closed. This will help people debug leaks.
doc/pgjdbc.xml | 22 +++++++++++++++++++++-
org/postgresql/Driver.java.in | 4 +++-
org/postgresql/jdbc2/AbstractJdbc2Connection.java | 18 +++++++++++++++++-
3 files changed, 41 insertions(+), 3 deletions(-)
diff --git a/doc/pgjdbc.xml b/doc/pgjdbc.xml
index 8a8970a5..17065fc8 100644
--- a/doc/pgjdbc.xml
+++ b/doc/pgjdbc.xml
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<!--
Copyright (c) 2004-2005, PostgreSQL Global Development Group
- $PostgreSQL: pgjdbc/doc/pgjdbc.xml,v 1.24 2005/03/04 07:10:13 jurka Exp $
+ $PostgreSQL: pgjdbc/doc/pgjdbc.xml,v 1.25 2005/04/10 15:15:05 jurka Exp $
-->
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
@@ -540,6 +540,26 @@ Connection conn = DriverManager.getConnection(url);
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>logUnclosedConnections</varname> = <type>boolean</type></term>
+ <listitem>
+ <para>
+ Clients may leak <classname>Connection</classname> objects by
+ failing to call its <function>close()</function> method.
+ Eventually these objects will be garbage collected and the
+ <function>finalize()</function> method will be called which will
+ close the <classname>Connection</classname> if caller has
+ neglected to do this himself. The usage of a finalizer is just
+ a stopgap solution. To help developers detect and correct the
+ source of these leaks the <literal>logUnclosedConnections</literal>
+ <acronym>URL</acronym> parameter has been added. It captures
+ a stacktrace at each <classname>Connection</classname> opening
+ and if the <function>finalize()</function> method is reached without
+ having been closed the stacktrace is printed to the log.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><varname>prepareThreshold</varname> = <type>int</type></term>
<listitem>
diff --git a/org/postgresql/Driver.java.in b/org/postgresql/Driver.java.in
index b545d58d..3b38a8ad 100644
--- a/org/postgresql/Driver.java.in
+++ b/org/postgresql/Driver.java.in
@@ -3,7 +3,7 @@
* Copyright (c) 2003-2005, PostgreSQL Global Development Group
*
* IDENTIFICATION
-* $PostgreSQL: pgjdbc/org/postgresql/Driver.java.in,v 1.64 2005/02/02 23:30:30 oliver Exp $
+* $PostgreSQL: pgjdbc/org/postgresql/Driver.java.in,v 1.65 2005/02/15 08:56:24 jurka Exp $
*
*-------------------------------------------------------------------------
*/
@@ -414,6 +414,8 @@ public class Driver implements java.sql.Driver
new String[] { "0", "1", "2" } },
{ "allowEncodingChanges", Boolean.FALSE,
"Allow the user to change the client_encoding variable." },
+ { "logUnclosedConnections", Boolean.FALSE,
+ "When connections that are not explicitly closed are garbage collected, log the stacktrace from the opening of the connection to trace the leak source."},
{ "prepareThreshold", Boolean.FALSE,
"Default statement prepare threshold (numeric)." },
{ "charSet", Boolean.FALSE,
diff --git a/org/postgresql/jdbc2/AbstractJdbc2Connection.java b/org/postgresql/jdbc2/AbstractJdbc2Connection.java
index 1a436b98..2e0ad685 100644
--- a/org/postgresql/jdbc2/AbstractJdbc2Connection.java
+++ b/org/postgresql/jdbc2/AbstractJdbc2Connection.java
@@ -3,7 +3,7 @@
* Copyright (c) 2004-2005, PostgreSQL Global Development Group
*
* IDENTIFICATION
-* $PostgreSQL: pgjdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java,v 1.31 2005/07/04 18:50:29 davec Exp $
+* $PostgreSQL: pgjdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java,v 1.32 2005/08/01 06:54:14 oliver Exp $
*
*-------------------------------------------------------------------------
*/
@@ -37,6 +37,8 @@ public abstract class AbstractJdbc2Connection implements BaseConnection
/* URL we were created via */
private final String creatingURL;
+ private final String openStackTrace;
+
/* Actual network handler */
private final ProtocolConnection protoConnection;
/* Compatibility version */
@@ -134,6 +136,16 @@ public abstract class AbstractJdbc2Connection implements BaseConnection
// Initialize object handling
_typeCache = new TypeInfoCache(this);
initObjectTypes(info);
+
+ if (Boolean.parseBoolean(info.getProperty("logUnclosedConnections"))) {
+ java.io.CharArrayWriter caw = new java.io.CharArrayWriter(1024);
+ Exception e = new Exception();
+ e.printStackTrace(new java.io.PrintWriter(caw));
+ openStackTrace = caw.toString();
+ enableDriverManagerLogging();
+ } else {
+ openStackTrace = null;
+ }
}
private final TimestampUtils timestampUtils;
@@ -795,6 +807,10 @@ public abstract class AbstractJdbc2Connection implements BaseConnection
*/
public void finalize() throws Throwable
{
+ if (openStackTrace != null && !isClosed()) {
+ DriverManager.println(GT.tr("Finalizing a Connection that was never closed. Connection was opened here:"));
+ DriverManager.println(openStackTrace);
+ }
close();
}
[parent: cb7113314937]