Hi Steve,
Thanks for the reply . This is a frequent error for us . So we need to fix this badly.
 
Here are more info to your questions...
 

1) What kind of system [hardware / OS / JVM] are you seeing this
error on?  - Intel 3.0Ghz Xion Based Servers/ Linux RH 4.0 / 1.4.2 Blackdown /Jboss

2) Approximately how frequently do you see this error? (Under normal
usage patterns, presuming an implementation of System.identityHashCode
() that tries hard to minimize collisions and infrequent construction
of c3p0 PooledDataSources this should be a very, very rare event.
It's a bug that it's very rare and not never, but still. Is this a
once-in-five-years or a seven-times-a-day event?)

Once in a few thousand connections (under heavy load)
Approx: 60 Connection Calls per minute continuously throughout the day.

We get about 10 such [c3p0 bug]'s per day.


3) How does your client code use c3p0 PooledDataSources? Do clients
look up the DataSource by JNDI each time the DataSource is used, or
do clients do a single JNDI-lookup, caching the DataSource for future
use? The latter use-pattern is the better one: from a performance
perspective, depending in the implementation o your name-service,
JNDI lookups can be quite slow, sometimes slow enough to obviate the
performance advantage of Connection pooling entirely if you do a
lookup for each Connection acquire. However, if you do lookup for
each acquisition, that would lead to a higher frequency of hash
collisions, as each JNDI lookup may require the reconstruction and
canonicalization of a Serialized or Referenceable PooledDataShort
(again, this depends on name service implementation).

// This is the JNDI code for the JBOSS

System.out.println("In C3PO [if] connection");

String _pool_name = "MyDB";

 

  if(ctx == null) throw new Exception("Boom - No Context");

  ds = (DataSource)ctx.lookup(JProps.getProperty("JBOSS_JNDI."+_pool_name));

  con = ds.getConnection();

 ------------------------------------------------

server/all/deploy/c3p1-service.xml

<?xml version="1.0" encoding="UTF-8" ?>

  <!DOCTYPE server (View Source for full doctype...)>
- <server>
- <mbean code="com.mchange.v2.c3p0.mbean.C3P0PooledDataSource" name="jboss:service=C3P0PooledDataSource1">
  <attribute name="JndiName">java:PooledDS1</attribute>
  <attribute name="JdbcUrl">jdbc:oracle:oci8:@MyDBstr</attribute>
  <attribute name="DriverClass"> oracle.jdbc.driver.OracleDriver</attribute>
  <attribute name="User">scott</attribute>
  <attribute name="Password">*****</attribute>
<attribute name="AutoCommitOnClose">true</attribute>
  <attribute name="AutomaticTestTable">dual</attribute>
 <attribute name="InitialPoolSize">1</attribute>
  <attribute name="MaxIdleTime">10</attribute>
  <attribute name="MaxPoolSize">15</attribute>
  <attribute name="MaxStatements">0</attribute>
  <attribute name="MaxStatementsPerConnection">0</attribute>
  <attribute name="MinPoolSize">3</attribute>
  <attribute name="PreferredTestQuery">select 1 from dual</attribute>
  <attribute name="TestConnectionOnCheckin">true</attribute>
  <attribute name="TestConnectionOnCheckout">false</attribute>
  <depends>jboss:service=Naming</depends>
  </mbean>
  </server>

 Thanks and regards,

~Prishan


 
On 7/23/06, Steve Waldman <swaldman@mchange.com> wrote:
Prishan,

First, apologies that your message doesn't seem to have made it
through to the list. I tried to approve it, but I think I messed up
somehow.

Anyway, the message you are seeing is quite fascinating. Really
fascinating. Check it:

> DBConnectionManager[getConnection]=javax.naming.NamingException:
> Could not dereference object [Root exception is
> java.lang.RuntimeException: [c3p0 bug] Only brand new
> IdentityTokenized's, with their identities just set, should be
> registered!!! Attempted to register
> com.mchange.v2.c3p0.WrapperConnectionPoolDataSource@17a159b
> [ acquireIncrement -> 3, acquireRetryAttempts -> 30,
> acquireRetryDelay -> 1000, autoCommitOnClose -> false,
> automaticTestTable -> null, breakAfterAcquireFailure -> false,
> checkoutTimeout -> 0, connectionTesterClassName ->
> com.mchange.v2.c3p0.impl.DefaultConnectionTester,
> factoryClassLocation -> null, forceIgnoreUnresolvedTransactions ->
> false, identityToken -> 17a159b, idleConnectionTestPeriod -> -1,
> initialPoolSize -> 3, maxIdleTime -> 0, maxPoolSize -> 15,
> maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize ->
> 3, nestedDataSource -> null, preferredTestQuery -> null,
> propertyCycle -> 300, testConnectionOnCheckin -> false,
> testConnectionOnCheckout -> false, usesTraditionalReflectiveProxies
> -> false; userOverrides: {} ] (with identity token 17a159b);
> Coalesced to com.mchange.v2.c3p0.PoolBackedDataSource@17a159b
> [ connectionPoolDataSource ->
> com.mchange.v2.c3p0.WrapperConnectionPoolDataSource@630763
> [ acquireIncrement -> 3, acquireRetryAttempts -> 30,
> acquireRetryDelay -> 1000, autoCommitOnClose -> true,
> automaticTestTable -> dual, breakAfterAcquireFailure -> false,
> checkoutTimeout -> 0, connectionTesterClassName ->
> com.mchange.v2.c3p0.impl.DefaultConnectionTester ,
> factoryClassLocation -> null, forceIgnoreUnresolvedTransactions ->
> false, identityToken -> 630763, idleConnectionTestPeriod -> -1,
> initialPoolSize -> 10, maxIdleTime -> 10, maxPoolSize -> 30,
> maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize ->
> 5, nestedDataSource ->
> com.mchange.v2.c3p0.DriverManagerDataSource@adccd6 [ description ->
> null, driverClass -> oracle.jdbc.driver.OracleDriver,
> factoryClassLocation -> null, identityToken -> adccd6, jdbcUrl ->
> jdbc:oracle:oci8:@test , properties -> {{user=******,
> password=******}} ], preferredTestQuery -> SELECT * FROM dual,
> propertyCycle -> 300, testConnectionOnCheckin -> true,
> testConnectionOnCheckout -> false, usesTraditionalReflectiveProxies
> -> false; userOverrides: {} ], factoryClassLocation -> null,
> identityToken -> 17a159b, numHelperThreads -> 10 ](with identity
> token 17a159b).]

Note that two java objects are shown as turning up the same
System.identityHasCode()!
com.mchange.v2.c3p0.WrapperConnectionPoolDataSource@17a159b and
com.mchange.v2.c3p0.PoolBackedDataSource@17a159b! They are both
ungarbage collected and in the same JVM at the same time! You've
blown my mind here.

Upon more research, it's quite good that you've blown my mind. I've
presumed in the implementation of c3p0 and some its underlying
libraries that System.identityHashCode() returns a unique ID for each
object. It turns out that this presumption is usually true in
practice in most JVM implementations, but not guaranteed to be true,
particularly in 64-bit VMs. My very, very bad. (I really did think
there was a uniqueness guarantee here, it's something I thought I
knew. Learn something new you've screwed up every day.)

Anyway, I'm going to have to work harder to check uniqueness in my
canonicalization libraries and in constructing c3p0 object identity
tokens in light of the sad information that there exists no facility
in java for extracting a guaranteed unique object ID. (Sun's
suggested workaround [ http://bugs.sun.com/bugdatabase/view_bug.do?
bug_id=4990451 ] is to map user-defined 64-bit IDs to objects in a
weak hash map when UIDs are required. I'll have to look into some
variant of that.)

In the meantime, could you provide me with a bit of information?

1) What kind of sysatem [hardware / OS / JVM] are you seeing this
error on?

2) Approximately how frequently do you see this error? (Under normal
usage patterns, presuming an implementation of System.identityHashCode
() that tries hard to minimize collisions and infrequent construction
of c3p0 PooledDataSources this should be a very, very rare event.
It's a bug that it's very rare and not never, but still. Is this a
once-in-five-years or a seven-times-a-day event?)

3) How does your client code use c3p0 PooledDataSources? Do clients
look up the DataSource by JNDI each time the DataSource is used, or
do clients do a single JNDI-lookup, caching the DataSource for future
use? The latter use-pattern is the better one: from a performance
perspective, depending in the implementation o your name-service,
JNDI lookups can be quite slow, sometimes slow enough to obviate the
performance advantage of Connection pooling entirely if you do a
lookup for each Connection acquire. However, if you do lookup for
each acquisition, that would lead to a higher frequency of hash
collisions, as each JNDI lookup may require the reconstruction and
canonicalization of a Serialized or Referenceable PooledDataShort
(again, this depends on name service implementation).

Anyway, thanks for this report. It's nice, even if a bit
embarrassing, to learn something new every day. And please do send me
a bit more information if you get a chance.

      smiles,
          Steve

---
Steve Waldman
Machinery For Change, Inc.