Thread: double Statement.close() (on AIX 5.1)

double Statement.close() (on AIX 5.1)

From
Victor Sergienko
Date:
Gentlemen,

I beg your pardon for incomplete problem description.

On AIX 5.1, IBM Java 1.3.1 I'm using pg74jdbc3.jar dated 24.12.03.
We have a flaw in a legacy program: it calls Statement.close() inside
try() and in finally{} - thus, two times.
On doing that, I get:

java.sql.SQLException: Statement has been closed
        at org.postgresql.jdbc2.optional.PooledConnectionImpl$StatementHandler.invoke(
PooledConnectionImpl.java(Compiled Code))
        at $Proxy1.close(Unknown Source)(Compiled Code)
        at SomeUserClass.someMethod(Something.java:1345)

As JDK java.sql.Statement.close() documentation specifies, calling
Statement.close() on already close()d statement should have no effect.
It's the way Oracle and MS SQL drivers behave, but PG driver throws
this exception.

A pity, I cannot reproduce this statement on my working desk on
Windows XP + Sun Java 1.3.1_02. If I get the possibility to debug on
AIX, I can report more precisely.

Looks like it's postgresql\jdbc2\optional\PooledConnectionImpl.java,
lines ~365:

            // All the rest is from the Statement interface
            if (st == null || con.isClosed())
            {
                throw new SQLException("Statement has been closed");
            }
            if (method.getName().equals("close"))
            {
                try {
                    st.close();
                } finally {
                    con = null;
                    st = null;
                    return null;
                }
            }

  As for me, this should look like:

            // All the rest is from the Statement interface
            if (method.getName().equals("close"))
            {
                try {
                    if (st != null && !con.isClosed()) st.close();
                } finally {
                    con = null;
                    st = null;
                    return null;
                }
            }
            if (st == null || con.isClosed())
            {
                throw new SQLException("Statement has been closed");
            }

  My question is: is it a known bug, an intended feature, or an
OS/JDK-specific bug that was not known before? What's wrong with my
suggestion?

Thank you.

--
Best regards,
 Victor Sergienko


Re: double Statement.close() (on AIX 5.1)

From
Dave Cramer
Date:
Victor,

You are absolutely correct this should not happen. You do however
realize that close on a PooledConnection returns it to the pool?

Dave
On Tue, 2004-02-24 at 05:07, Victor Sergienko wrote:
> Gentlemen,
>
> I beg your pardon for incomplete problem description.
>
> On AIX 5.1, IBM Java 1.3.1 I'm using pg74jdbc3.jar dated 24.12.03.
> We have a flaw in a legacy program: it calls Statement.close() inside
> try() and in finally{} - thus, two times.
> On doing that, I get:
>
> java.sql.SQLException: Statement has been closed
>         at org.postgresql.jdbc2.optional.PooledConnectionImpl$StatementHandler.invoke(
> PooledConnectionImpl.java(Compiled Code))
>         at $Proxy1.close(Unknown Source)(Compiled Code)
>         at SomeUserClass.someMethod(Something.java:1345)
>
> As JDK java.sql.Statement.close() documentation specifies, calling
> Statement.close() on already close()d statement should have no effect.
> It's the way Oracle and MS SQL drivers behave, but PG driver throws
> this exception.
>
> A pity, I cannot reproduce this statement on my working desk on
> Windows XP + Sun Java 1.3.1_02. If I get the possibility to debug on
> AIX, I can report more precisely.
>
> Looks like it's postgresql\jdbc2\optional\PooledConnectionImpl.java,
> lines ~365:
>
>             // All the rest is from the Statement interface
>             if (st == null || con.isClosed())
>             {
>                 throw new SQLException("Statement has been closed");
>             }
>             if (method.getName().equals("close"))
>             {
>                 try {
>                     st.close();
>                 } finally {
>                     con = null;
>                     st = null;
>                     return null;
>                 }
>             }
>
>   As for me, this should look like:
>
>             // All the rest is from the Statement interface
>             if (method.getName().equals("close"))
>             {
>                 try {
>                     if (st != null && !con.isClosed()) st.close();
>                 } finally {
>                     con = null;
>                     st = null;
>                     return null;
>                 }
>             }
>             if (st == null || con.isClosed())
>             {
>                 throw new SQLException("Statement has been closed");
>             }
>
>   My question is: is it a known bug, an intended feature, or an
> OS/JDK-specific bug that was not known before? What's wrong with my
> suggestion?
>
> Thank you.
>
--
Dave Cramer
519 939 0336
ICQ # 14675561


Re: double Statement.close() (on AIX 5.1)

From
Kris Jurka
Date:

On Tue, 24 Feb 2004, Victor Sergienko wrote:

> Gentlemen,
>
> I beg your pardon for incomplete problem description.
>
> On AIX 5.1, IBM Java 1.3.1 I'm using pg74jdbc3.jar dated 24.12.03.
> We have a flaw in a legacy program: it calls Statement.close() inside
> try() and in finally{} - thus, two times.
> On doing that, I get:
>
> java.sql.SQLException: Statement has been closed
>
> As JDK java.sql.Statement.close() documentation specifies, calling
> Statement.close() on already close()d statement should have no effect.


This is a problem in a number of other places (the pooled Connection and
the regular Statement) as well.  I have applied a patch to both the 7.4
and development cvs repositories.  Pre-built jar files are available here:
http://www.ejurka.com/pgsql/jars/

Also if you are using the 1.3 JDK you shouldn't be using the JDBC 3 jar.
This should only be used with the 1.4 JDK.  You probably want the
jdbc2ee.jar file.

Thanks for the report.

Kris Jurka


Re: double Statement.close() (on AIX 5.1)

From
Victor Sergienko
Date:
Hello Dave,

  I understand that. However, the other JDBC drivers we use don't have
such an issue. Their connection pool might remember the statement's
owner thread or something excessive like that.
  Anyway, it's not about close()s on Connection, just on Statement or
PreparedStatement.
  And moreover, implementation issues should not affect interface.

DC> You are absolutely correct this should not happen. You do however
DC> realize that close on a PooledConnection returns it to the pool?
 [skip]

>> As JDK java.sql.Statement.close() documentation specifies, calling
>> Statement.close() on already close()d statement should have no effect.
>> It's the way Oracle and MS SQL drivers behave, but PG driver throws
>> this exception.
 [skip]
>> Thank you.

Thank you and thank Kris.

--
Best regards,
 Victor                            mailto:singalen@mail.ru