Обсуждение: PGXAConnection ConnectionHandler equals bug

Поиск
Список
Период
Сортировка

PGXAConnection ConnectionHandler equals bug

От
Florent Guillaume
Дата:
Hi,

When you have a Connection coming from a XAConnection, the equals()
method doesn't work: conn.equals(conn) returns false.

The reason is that it's a actually a wapper, a
org.postgresql.xa.PGXAConnection.ConnectionHandler, and its invoke()
method doesn't take into account the "equals" case to unwrap the
second argument as well if needed.

I observed this bug using the driver with Apache commons-dbcp and a XA
datasource factory.
FYI this is tracked in our code base as https://jira.nuxeo.com/browse/NXP-6985

Here's a unit test and patch for it.

Regards,
Florent

diff --git a/org/postgresql/test/xa/XADataSourceTest.java
b/org/postgresql/test/xa/XADataSourceTest.java
index ea316fb..6e8e300 100644
--- a/org/postgresql/test/xa/XADataSourceTest.java
+++ b/org/postgresql/test/xa/XADataSourceTest.java
@@ -130,6 +130,10 @@ public class XADataSourceTest extends TestCase {
         }
     }

+    public void testWrapper() throws Exception {
+        assertTrue("Wrappers should be equal", conn.equals(conn));
+    }
+
     public void testOnePhase() throws Exception {
         Xid xid = new CustomXid(1);
         xaRes.start(xid, XAResource.TMNOFLAGS);
diff --git a/org/postgresql/xa/PGXAConnection.java
b/org/postgresql/xa/PGXAConnection.java
index ee84488..8386226 100644
--- a/org/postgresql/xa/PGXAConnection.java
+++ b/org/postgresql/xa/PGXAConnection.java
@@ -153,6 +153,16 @@ public class PGXAConnection extends
PGPooledConnection implements XAConnection,
                 }
             }
             try {
+                if (method.getName().equals("equals")) {
+                    Object arg = args[0];
+                    if (Proxy.isProxyClass(arg.getClass())) {
+                        InvocationHandler h = Proxy.getInvocationHandler(arg);
+                        if (h instanceof ConnectionHandler) {
+                            // unwrap argument
+                            args = new Object[] {
((ConnectionHandler) h).con };
+                        }
+                    }
+                }
                 return method.invoke(con, args);
             } catch (InvocationTargetException ex) {
                 throw ex.getTargetException();


--
Florent Guillaume, Director of R&D, Nuxeo
Open Source, Java EE based, Enterprise Content Management (ECM)
http://www.nuxeo.com   http://www.nuxeo.org   +33 1 40 33 79 87

Re: PGXAConnection ConnectionHandler equals bug

От
"Kevin Grittner"
Дата:
Florent Guillaume <fg@nuxeo.com> wrote:

> When you have a Connection coming from a XAConnection, the
> equals() method doesn't work: conn.equals(conn) returns false.
>
> The reason is that it's a actually a wapper, a
> org.postgresql.xa.PGXAConnection.ConnectionHandler, and its
> invoke() method doesn't take into account the "equals" case to
> unwrap the second argument as well if needed.

Is the hashCode method OK?  (What affects equals usually affects
hashCode, too.)

-Kevin

Re: PGXAConnection ConnectionHandler equals bug

От
Florent Guillaume
Дата:
On Mon, Oct 17, 2011 at 7:28 PM, Kevin Grittner
<Kevin.Grittner@wicourts.gov> wrote:
> Florent Guillaume <fg@nuxeo.com> wrote:
>> When you have a Connection coming from a XAConnection, the
>> equals() method doesn't work: conn.equals(conn) returns false.
>>
>> The reason is that it's a actually a wapper, a
>> org.postgresql.xa.PGXAConnection.ConnectionHandler, and its
>> invoke() method doesn't take into account the "equals" case to
>> unwrap the second argument as well if needed.
>
> Is the hashCode method OK?  (What affects equals usually affects
> hashCode, too.)

Yes, hashCode is delegated down the chain to the underlying
AbstractJdbc23PooledConnection.ConnectionHandler#invoke which has
consistent equals and hashCode.

Florent




--
Florent Guillaume, Director of R&D, Nuxeo
Open Source, Java EE based, Enterprise Content Management (ECM)
http://www.nuxeo.com   http://www.nuxeo.org   +33 1 40 33 79 87