views:

247

answers:

1

If I put the wrong connection URL in my hibernate.cfg.xml file, I want to be able to detect it and terminate gracefully, but I can't figure out how; it just hangs indefinitely on buildSessionFactory() during the hibernate initialisation procedure:

SessionFactory sf = new AnnotationConfiguration().configure().buildSessionFactory();

It's in a try block, and I'm trying to catch a generic Exception, but buildSessionFactory() never throws one, it just hangs. This is the URL element in my hibernate.cfg.xml:

<property name="hibernate.connection.url">jdbc:mysql://123.123.123.123/mydb</property>

My system: Ubuntu 9.10 with Tomcat 5.5, Java 1.6, Hibernate 3 and MySQL 5.

When I first initialise hibernate, it just hangs for 22 seconds, then starts spitting out warnings about threads and deadlock (starting with this):

15:16:25,758  WARN ThreadPoolAsynchronousRunner.class: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@a010ba -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
15:16:25,761  WARN ThreadPoolAsynchronousRunner.class: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@a010ba -- APPARENT DEADLOCK!!! Complete Status: 
Managed Threads: 3
Active Threads: 3
Active Tasks: 
    com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@109da93 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0)
    com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@1ed1dbe (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2)
    com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@3bc1a1 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1)
Pending Tasks: 
    com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@12549c4
    com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@10df4e2
Pool thread stack traces:
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0,5,main]
    java.net.PlainSocketImpl.socketConnect(Native Method)
    java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
    java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
    java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
    java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
    java.net.Socket.connect(Socket.java:525)
    java.net.Socket.connect(Socket.java:475)
    java.net.Socket.<init>(Socket.java:372)
    java.net.Socket.<init>(Socket.java:215)
    com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:253)
    com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:284)
    com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2194)
    com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:723)
    com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:46)
    sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
    com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:302)
    com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:282)
    com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:135)
    com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:182)
    com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:171)
    com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:137)
    com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1014)
    com.mchange.v2.resourcepool.BasicResourcePool.access$800(BasicResourcePool.java:32)
    com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.java:1810)
    com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)

EDIT: here's my c3p0 properties from my hibernate.cfg.xml

<property name="hibernate.c3p0.acquire_increment">1</property>
<property name="hibernate.c3p0.idle_test_period">100</property>
<property name="hibernate.c3p0.max_size">100</property>
<property name="hibernate.c3p0.max_statements">100</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.timeout">100</property>
A: 

As BryanD mentioned in a comment, buildSessionFactory() is not really hanging, the time is very likely spent in c3p0 which is trying to reconnect. Quoting the c3p0 documentation:

When a c3p0 DataSource attempts and fails to acquire a Connection, it will retry up to acquireRetryAttempts times, with a delay of acquireRetryDelay between each attempt. If all attempts fail, any clients waiting for Connections from the DataSource will see an Exception, indicating that a Connection could not be acquired. Note that clients do not see any Exception until a full round of attempts fail, which may be some time after the initial Connection attempt. If acquireRetryAttempts is set to 0, c3p0 will attempt to acquire new Connections indefinitely, and calls to getConnection() may block indefinitely waiting for a successful acquisition.

If you didn't configure it, the default value of the acquireRetryAttempts is 30 so it may indeed take some time for buildSessionFactory() to return. But, unless you used a value less than or equal to zero in which case c3p0 will keep trying to fetch a Connection indefinitely, it will.

Maybe you could use a lower value. Or maybe you could just use the right URL and stop spending time on an exceptional situation (a configuration mistake).

Pascal Thivent
Thanks for the info. I tried setting c3p0.acquireRetryAttempts=1 (and confirmed it was set with the debug output) but it behaved exactly the same. I only ask about all this because I'm testing my app on a few different servers, and I wasted plenty of time figuring out what was wrong when the app just hung indefinitely when I'd simply forgotten to update the connection URL. I thought there might be a simple fix to catch this error to save myself and others from wasting time debugging configuration mistakes in the future...
jackocnr