> The following bug has been logged online: > > Bug reference: 1065 > Logged by: R. Lemos > > The JDBC2 pooled datasource(org.postgresql.jdbc2.optional.ConnectionPool), > although implements java.io.Serializable, cannot be correctly serialized. > Its superclass does not implement java.io.Serializable and have important > fields marked as private.
The BaseDataSource class cannot be made Serializable because one of its subclasses (PoolingDataSource) cannot be serialized. The PoolingDataSource class has member variables which can contain active database connections which can't be persisted. > Either should the superclass be Serializable or its fields non-private > (protected, friend or public). > Simply marking the fields with a weaker access level won't magically persist them. This requires manually using writeObject and readObject. This problem also occurs in SimpleDataSource. I've attached the patch I've applied to the gborg cvs repository. Thanks for the report. Kris Jurka
? doc ? mine.pdf ? mybuild.xml Index: org/postgresql/jdbc2/optional/BaseDataSource.java =================================================================== RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/jdbc2/optional/BaseDataSource.java,v retrieving revision 1.3 diff -c -r1.3 BaseDataSource.java *** org/postgresql/jdbc2/optional/BaseDataSource.java 25 Sep 2002 07:01:30 -0000 1.3 --- org/postgresql/jdbc2/optional/BaseDataSource.java 26 Jan 2004 12:59:59 -0000 *************** *** 4,9 **** --- 4,13 ---- import java.io.PrintWriter; import java.sql.*; + import java.io.ObjectOutputStream; + import java.io.ObjectInputStream; + import java.io.IOException; + /** * Base class for data sources and related classes. * *************** *** 53,59 **** /** * Gets a connection to the PostgreSQL database. The database is identified by the ! * DataAource properties serverName, databaseName, and portNumber. The user to * connect as is identified by the arguments user and password, which override * the DataSource properties by the same name. * --- 57,63 ---- /** * Gets a connection to the PostgreSQL database. The database is identified by the ! * DataSource properties serverName, databaseName, and portNumber. The user to * connect as is identified by the arguments user and password, which override * the DataSource properties by the same name. * *************** *** 260,265 **** --- 264,287 ---- ref.add(new StringRefAddr("password", password)); } return ref; + } + + protected void writeBaseObject(ObjectOutputStream out) throws IOException + { + out.writeObject(serverName); + out.writeObject(databaseName); + out.writeObject(user); + out.writeObject(password); + out.writeInt(portNumber); + } + + protected void readBaseObject(ObjectInputStream in) throws IOException, ClassNotFoundException + { + serverName = (String)in.readObject(); + databaseName = (String)in.readObject(); + user = (String)in.readObject(); + password = (String)in.readObject(); + portNumber = in.readInt(); } } Index: org/postgresql/jdbc2/optional/ConnectionPool.java =================================================================== RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/jdbc2/optional/ConnectionPool.java,v retrieving revision 1.2 diff -c -r1.2 ConnectionPool.java *** org/postgresql/jdbc2/optional/ConnectionPool.java 6 Sep 2002 21:23:06 -0000 1.2 --- org/postgresql/jdbc2/optional/ConnectionPool.java 26 Jan 2004 12:59:59 -0000 *************** *** 4,9 **** --- 4,12 ---- import javax.sql.PooledConnection; import java.sql.SQLException; import java.io.Serializable; + import java.io.ObjectOutputStream; + import java.io.ObjectInputStream; + import java.io.IOException; /** * PostgreSQL implementation of ConnectionPoolDataSource. The app server or *************** *** 79,82 **** --- 82,96 ---- this.defaultAutoCommit = defaultAutoCommit; } + private void writeObject(ObjectOutputStream out) throws IOException + { + writeBaseObject(out); + out.writeBoolean(defaultAutoCommit); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException + { + readBaseObject(in); + defaultAutoCommit = in.readBoolean(); + } } Index: org/postgresql/jdbc2/optional/SimpleDataSource.java =================================================================== RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/jdbc2/optional/SimpleDataSource.java,v retrieving revision 1.2 diff -c -r1.2 SimpleDataSource.java *** org/postgresql/jdbc2/optional/SimpleDataSource.java 6 Sep 2002 21:23:06 -0000 1.2 --- org/postgresql/jdbc2/optional/SimpleDataSource.java 26 Jan 2004 12:59:59 -0000 *************** *** 2,7 **** --- 2,10 ---- import javax.sql.DataSource; import java.io.Serializable; + import java.io.ObjectOutputStream; + import java.io.ObjectInputStream; + import java.io.IOException; /** * Simple DataSource which does not perform connection pooling. In order to use *************** *** 20,24 **** --- 23,37 ---- public String getDescription() { return "Non-Pooling DataSource from " + org.postgresql.Driver.getVersion(); + } + + private void writeObject(ObjectOutputStream out) throws IOException + { + writeBaseObject(out); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException + { + readBaseObject(in); } } Index: org/postgresql/test/jdbc2/optional/ConnectionPoolTest.java =================================================================== RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/test/jdbc2/optional/ConnectionPoolTest.java,v retrieving revision 1.8 diff -c -r1.8 ConnectionPoolTest.java *** org/postgresql/test/jdbc2/optional/ConnectionPoolTest.java 12 Dec 2003 18:05:34 -0000 1.8 --- org/postgresql/test/jdbc2/optional/ConnectionPoolTest.java 26 Jan 2004 12:59:59 -0000 *************** *** 4,9 **** --- 4,10 ---- import org.postgresql.test.TestUtil; import javax.sql.*; import java.sql.*; + import java.io.*; /** * Tests for the ConnectionPoolDataSource and PooledConnection *************** *** 493,496 **** --- 494,524 ---- count = errorCount = 0; } } + + public void testSerializable() throws IOException, ClassNotFoundException + { + ConnectionPool pool = new ConnectionPool(); + pool.setDefaultAutoCommit(false); + pool.setServerName("db.myhost.com"); + pool.setDatabaseName("mydb"); + pool.setUser("user"); + pool.setPassword("pass"); + pool.setPortNumber(1111); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(pool); + + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(bais); + ConnectionPool pool2 = (ConnectionPool)ois.readObject(); + + assertEquals(pool.isDefaultAutoCommit(),pool2.isDefaultAutoCommit()); + assertEquals(pool.getServerName(),pool2.getServerName()); + assertEquals(pool.getDatabaseName(),pool2.getDatabaseName()); + assertEquals(pool.getUser(),pool2.getUser()); + assertEquals(pool.getPassword(),pool2.getPassword()); + assertEquals(pool.getPortNumber(),pool2.getPortNumber()); + } + }
---------------------------(end of broadcast)--------------------------- TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]