Thread: ClassCastException with LargeObjectAPI and Tomcat Connection Pool (DBCP)

ClassCastException with LargeObjectAPI and Tomcat Connection Pool (DBCP)

From
Joao Filipe Placido
Date:

Hello list,

I configured successfully a PostgreSQL 7.2.3 connection pool with JNDI DataSource following the Tomcat docs (v 4.1.12).

But when I try to use the returned connection with the LargeObjectAPI, tomcat gives me a ClassCastException (runtime), in the following line:

LargeObjectManager lobj = ((org.postgresql.PGConnection)db).getLargeObjectAPI();

I tried using pgjdbc2.jar, in which case instead of org.postgresql.PGConnection, it only works with org.postgresql.Connection.

With pg73jdbc3.jar, and using org.postgresql.PGConnection, the same Exception occurs.

I also tried with a compiled JDBC jar from the 7.3 sources, with no luck.

I don't understand why the connection works with non-LargeObject SQL and fails here. I have the same jars working with the LargeObjectAPI without the Tomcat DBCP.

Any help is appreciated. Has anyone successfully configured a tomcat DBCP with PostgresSQL and used LOs with it?

Thank you,

João Filipe Plácido

Re: ClassCastException with LargeObjectAPI and Tomcat Connection

From
Aaron Mulder
Date:
    When you use a DataSource, the connection returned is not an
org.postgresql.PGConnection, so the ClassCastException would be expected.
The connection is usually wrapped (though I'd have to look at the Tomcat
impl to be sure) because the behavior is supposed to be different for
pooled connections (in particular, close, and often setAutoCommit).
    Now that I look at it, we could easily enough make the PostgreSQL
pooled connections implement PGConnection, and then you could just use the
PostgreSQL DataSource instead of the Tomcat DataSource.

Aaron

On Fri, 3 Jan 2003, Joao Filipe Placido wrote:
> Hello list,
>
> I configured successfully a PostgreSQL 7.2.3 connection pool with JNDI
> DataSource following the Tomcat docs (v 4.1.12).
> But when I try to use the returned connection with the LargeObjectAPI,
> tomcat gives me a ClassCastException (runtime), in the following line:
>
> LargeObjectManager lobj =
> ((org.postgresql.PGConnection)db).getLargeObjectAPI();
>
> I tried using pgjdbc2.jar, in which case instead of
> org.postgresql.PGConnection, it only works with org.postgresql.Connection.
> With pg73jdbc3.jar, and using org.postgresql.PGConnection, the same
> Exception occurs.
> I also tried with a compiled JDBC jar from the 7.3 sources, with no luck.
>
> I don't understand why the connection works with non-LargeObject SQL and
> fails here. I have the same jars working with the LargeObjectAPI without the
> Tomcat DBCP.
> Any help is appreciated. Has anyone successfully configured a tomcat DBCP
> with PostgresSQL and used LOs with it?
>
> Thank you,
>
> João Filipe Plácido
>
>



Patch so Pooled Connections are PGConnections

From
Aaron Mulder
Date:
    Here's a patch that demonstrates the problem in the test class and
fixes it in the pooled connection class.  This makes all pooled
connections implement PGConnection (in addition to java.sql.Connection),
so if you use the PostgreSQL connection pools you can still use the
PGConnection API.  Still won't help if you use the native Tomcat pools,
but you can always use the PostgreSQL pools in Tomcat.

Aaron

On Fri, 3 Jan 2003, Aaron Mulder wrote:
>     When you use a DataSource, the connection returned is not an
> org.postgresql.PGConnection, so the ClassCastException would be expected.
> The connection is usually wrapped (though I'd have to look at the Tomcat
> impl to be sure) because the behavior is supposed to be different for
> pooled connections (in particular, close, and often setAutoCommit).
>     Now that I look at it, we could easily enough make the PostgreSQL
> pooled connections implement PGConnection, and then you could just use the
> PostgreSQL DataSource instead of the Tomcat DataSource.
>
> Aaron
>
> On Fri, 3 Jan 2003, Joao Filipe Placido wrote:
> > Hello list,
> >
> > I configured successfully a PostgreSQL 7.2.3 connection pool with JNDI
> > DataSource following the Tomcat docs (v 4.1.12).
> > But when I try to use the returned connection with the LargeObjectAPI,
> > tomcat gives me a ClassCastException (runtime), in the following line:
> >
> > LargeObjectManager lobj =
> > ((org.postgresql.PGConnection)db).getLargeObjectAPI();
> >
> > I tried using pgjdbc2.jar, in which case instead of
> > org.postgresql.PGConnection, it only works with org.postgresql.Connection.
> > With pg73jdbc3.jar, and using org.postgresql.PGConnection, the same
> > Exception occurs.
> > I also tried with a compiled JDBC jar from the 7.3 sources, with no luck.
> >
> > I don't understand why the connection works with non-LargeObject SQL and
> > fails here. I have the same jars working with the LargeObjectAPI without the
> > Tomcat DBCP.
> > Any help is appreciated. Has anyone successfully configured a tomcat DBCP
> > with PostgresSQL and used LOs with it?
> >
> > Thank you,
> >
> > João Filipe Plácido
> >
> >
>
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 3: if posting/reading through Usenet, please send an appropriate
> subscribe-nomail command to majordomo@postgresql.org so that your
> message can get through to the mailing list cleanly
>

Attachment

Re: Patch so Pooled Connections are PGConnections

From
Barry Lind
Date:
Aaron,

Patch applied to head.  I had problems applying the patch to the 7.3
branch.  If you would like it applied to 7.3, could you submit a new
diff against that branch?

thanks,
--Barry


Aaron Mulder wrote:
>     Here's a patch that demonstrates the problem in the test class and
> fixes it in the pooled connection class.  This makes all pooled
> connections implement PGConnection (in addition to java.sql.Connection),
> so if you use the PostgreSQL connection pools you can still use the
> PGConnection API.  Still won't help if you use the native Tomcat pools,
> but you can always use the PostgreSQL pools in Tomcat.
>
> Aaron
>
> On Fri, 3 Jan 2003, Aaron Mulder wrote:
>
>>    When you use a DataSource, the connection returned is not an
>>org.postgresql.PGConnection, so the ClassCastException would be expected.
>>The connection is usually wrapped (though I'd have to look at the Tomcat
>>impl to be sure) because the behavior is supposed to be different for
>>pooled connections (in particular, close, and often setAutoCommit).
>>    Now that I look at it, we could easily enough make the PostgreSQL
>>pooled connections implement PGConnection, and then you could just use the
>>PostgreSQL DataSource instead of the Tomcat DataSource.
>>
>>Aaron
>>
>>On Fri, 3 Jan 2003, Joao Filipe Placido wrote:
>>
>>>Hello list,
>>>
>>>I configured successfully a PostgreSQL 7.2.3 connection pool with JNDI
>>>DataSource following the Tomcat docs (v 4.1.12).
>>>But when I try to use the returned connection with the LargeObjectAPI,
>>>tomcat gives me a ClassCastException (runtime), in the following line:
>>>
>>>LargeObjectManager lobj =
>>>((org.postgresql.PGConnection)db).getLargeObjectAPI();
>>>
>>>I tried using pgjdbc2.jar, in which case instead of
>>>org.postgresql.PGConnection, it only works with org.postgresql.Connection.
>>>With pg73jdbc3.jar, and using org.postgresql.PGConnection, the same
>>>Exception occurs.
>>>I also tried with a compiled JDBC jar from the 7.3 sources, with no luck.
>>>
>>>I don't understand why the connection works with non-LargeObject SQL and
>>>fails here. I have the same jars working with the LargeObjectAPI without the
>>>Tomcat DBCP.
>>>Any help is appreciated. Has anyone successfully configured a tomcat DBCP
>>>with PostgresSQL and used LOs with it?
>>>
>>>Thank you,
>>>
>>>João Filipe Plácido
>>>
>>>
>>
>>
>>
>>---------------------------(end of broadcast)---------------------------
>>TIP 3: if posting/reading through Usenet, please send an appropriate
>>subscribe-nomail command to majordomo@postgresql.org so that your
>>message can get through to the mailing list cleanly
>>
>>
>>
>>------------------------------------------------------------------------
>>
>>Index: PooledConnectionImpl.java
>>===================================================================
>>RCS file:
/projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc2/optional/PooledConnectionImpl.java,v
>>retrieving revision 1.5
>>diff -c -r1.5 PooledConnectionImpl.java
>>*** PooledConnectionImpl.java    2002/12/20 14:10:34    1.5
>>--- PooledConnectionImpl.java    2003/01/03 19:59:26
>>***************
>>*** 4,9 ****
>>--- 4,10 ----
>>  import java.sql.*;
>>  import java.util.*;
>>  import java.lang.reflect.*;
>>+ import org.postgresql.PGConnection;
>>
>>  /**
>>   * PostgreSQL implementation of the PooledConnection interface.  This shouldn't
>>***************
>>*** 114,120 ****
>>          con.setAutoCommit(autoCommit);
>>          ConnectionHandler handler = new ConnectionHandler(con);
>>          last = handler;
>>!         Connection con = (Connection)Proxy.newProxyInstance(getClass().getClassLoader(), new
Class[]{Connection.class},handler); 
>>          last.setProxy(con);
>>          return con;
>>      }
>>--- 115,121 ----
>>          con.setAutoCommit(autoCommit);
>>          ConnectionHandler handler = new ConnectionHandler(con);
>>          last = handler;
>>!         Connection con = (Connection)Proxy.newProxyInstance(getClass().getClassLoader(), new
Class[]{Connection.class,PGConnection.class}, handler); 
>>          last.setProxy(con);
>>          return con;
>>      }
>>***************
>>*** 213,219 ****
>>                                      throw e.getTargetException();
>>                                  }
>>              }
>>!             // All the rest is from the Connection interface
>>              if (method.getName().equals("isClosed"))
>>              {
>>                  return con == null ? Boolean.TRUE : Boolean.FALSE;
>>--- 214,220 ----
>>                                      throw e.getTargetException();
>>                                  }
>>              }
>>!             // All the rest is from the Connection or PGConnection interface
>>              if (method.getName().equals("isClosed"))
>>              {
>>                  return con == null ? Boolean.TRUE : Boolean.FALSE;
>>
>>
>>------------------------------------------------------------------------
>>
>>Index: BaseDataSourceTest.java
>>===================================================================
>>RCS file:
/projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/test/jdbc2/optional/BaseDataSourceTest.java,v
>>retrieving revision 1.4
>>diff -c -r1.4 BaseDataSourceTest.java
>>*** BaseDataSourceTest.java    2002/09/25 07:01:30    1.4
>>--- BaseDataSourceTest.java    2003/01/03 20:00:09
>>***************
>>*** 3,8 ****
>>--- 3,9 ----
>>  import junit.framework.TestCase;
>>  import org.postgresql.test.TestUtil;
>>  import org.postgresql.jdbc2.optional.BaseDataSource;
>>+ import org.postgresql.PGConnection;
>>
>>  import java.sql.*;
>>  import java.util.*;
>>***************
>>*** 178,183 ****
>>--- 179,202 ----
>>              fail(e.getMessage());
>>          }
>>      }
>>+
>>+     /**
>>+      * Test to make sure that PGConnection methods can be called on the
>>+      * pooled Connection.
>>+      */
>>+     public void testPGConnection()
>>+     {
>>+         try
>>+         {
>>+             con = getDataSourceConnection();
>>+             ((PGConnection)con).getEncoding().name();
>>+             con.close();
>>+         }
>>+         catch (Exception e)
>>+         {
>>+             fail("Unable to call PGConnection method on pooled connection due to "+e.getClass().getName()+"
("+e.getMessage()+")");
>>+         }
>>+     }
>>
>>      /**
>>       * Uses the mini-JNDI implementation for testing purposes
>>
>>
>>------------------------------------------------------------------------
>>
>>
>>---------------------------(end of broadcast)---------------------------
>>TIP 6: Have you searched our list archives?
>>
>>http://archives.postgresql.org