impossibl / pgjdbc-ng

A new JDBC driver for PostgreSQL aimed at supporting the advanced features of JDBC and Postgres
https://impossibl.github.io/pgjdbc-ng
Other
602 stars 108 forks source link

SSL connection problem #168

Closed mgaido91 closed 8 years ago

mgaido91 commented 9 years ago

Hello,

I'm facing big problem while trying to connect to a DB using SSL and your library... I've tried many connection strings, but none works. Do you know what can I do? In fact, I'm getting this exception:

java.sql.SQLException: Connection Error: java.lang.IllegalStateException at com.impossibl.postgres.jdbc.ConnectionUtil.createConnection(ConnectionUtil.java:189) at com.impossibl.postgres.jdbc.PGDriver.connect(PGDriver.java:77) at com.impossibl.postgres.jdbc.PGDriver.connect(PGDriver.java:52) at java.sql.DriverManager.getConnection(DriverManager.java:179) at it.polito.mobile.testpostgres.MainActivity$1.doInBackground(MainActivity.java:60) at it.polito.mobile.testpostgres.MainActivity$1.doInBackground(MainActivity.java:35) at android.os.AsyncTask$2.call(AsyncTask.java:288) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) at java.lang.Thread.run(Thread.java:818) Caused by: java.io.IOException: java.lang.IllegalStateException at com.impossibl.postgres.protocol.v30.ProtocolFactoryImpl.translateConnectionException(ProtocolFactoryImpl.java:285) at com.impossibl.postgres.protocol.v30.ProtocolFactoryImpl.connect(ProtocolFactoryImpl.java:199) at com.impossibl.postgres.protocol.v30.ProtocolFactoryImpl.connect(ProtocolFactoryImpl.java:90) at com.impossibl.postgres.system.BasicContext.<init>(BasicContext.java:130) at com.impossibl.postgres.jdbc.PGConnectionImpl.<init>(PGConnectionImpl.java:185) at com.impossibl.postgres.jdbc.ConnectionUtil.createConnection(ConnectionUtil.java:180) ... 11 more Caused by: java.lang.IllegalStateException at io.netty.handler.ssl.SslHandler$LazyChannelPromise.executor(SslHandler.java:1491) at io.netty.util.concurrent.DefaultPromise.checkDeadLock(DefaultPromise.java:388) at io.netty.util.concurrent.DefaultPromise.awaitUninterruptibly(DefaultPromise.java:283) at io.netty.util.concurrent.DefaultPromise.syncUninterruptibly(DefaultPromise.java:225) at io.netty.util.concurrent.DefaultPromise.syncUninterruptibly(DefaultPromise.java:32) at com.impossibl.postgres.protocol.v30.ProtocolFactoryImpl.connect(ProtocolFactoryImpl.java:132) ... 15 more

harbulot commented 9 years ago

I can also reproduce the problem when getting a connection with SSL mode Require fails:

    Class.forName("com.impossibl.postgres.jdbc.PGDriver");
    String url = "jdbc:pgsql://host.example/test?ssl.mode=Require";
    Connection conn = DriverManager.getConnection(url, "test", "...");

This produces this exception (most of the time):

java.sql.SQLException: Connection Error: java.lang.IllegalStateException
    at com.impossibl.postgres.jdbc.ConnectionUtil.createConnection(ConnectionUtil.java:189)
    at com.impossibl.postgres.jdbc.PGDriver.connect(PGDriver.java:77)
    at com.impossibl.postgres.jdbc.PGDriver.connect(PGDriver.java:1)
    at java.sql.DriverManager.getConnection(DriverManager.java:664)
    at java.sql.DriverManager.getConnection(DriverManager.java:247)
    at test.MyTest.main(MyTest.java:58)
Caused by: java.io.IOException: java.lang.IllegalStateException
    at com.impossibl.postgres.protocol.v30.ProtocolFactoryImpl.translateConnectionException(ProtocolFactoryImpl.java:287)
    at com.impossibl.postgres.protocol.v30.ProtocolFactoryImpl.connect(ProtocolFactoryImpl.java:201)
    at com.impossibl.postgres.protocol.v30.ProtocolFactoryImpl.connect(ProtocolFactoryImpl.java:91)
    at com.impossibl.postgres.system.BasicContext.<init>(BasicContext.java:130)
    at com.impossibl.postgres.jdbc.PGConnectionImpl.<init>(PGConnectionImpl.java:185)
    at com.impossibl.postgres.jdbc.ConnectionUtil.createConnection(ConnectionUtil.java:180)
    ... 6 more
Caused by: java.lang.IllegalStateException
    at io.netty.handler.ssl.SslHandler$LazyChannelPromise.executor(SslHandler.java:1527)
    at io.netty.util.concurrent.DefaultPromise.checkDeadLock(DefaultPromise.java:388)
    at io.netty.util.concurrent.DefaultPromise.awaitUninterruptibly(DefaultPromise.java:283)
    at io.netty.util.concurrent.DefaultPromise.syncUninterruptibly(DefaultPromise.java:225)
    at io.netty.util.concurrent.DefaultPromise.syncUninterruptibly(DefaultPromise.java:32)
    at com.impossibl.postgres.protocol.v30.ProtocolFactoryImpl.connect(ProtocolFactoryImpl.java:134)
    ... 10 more

This is caused by the call to syncUninterruptibly:

sslHandler.handshakeFuture().syncUninterruptibly();

This is almost certainly due to a race condition regarding when ctx is set in Netty's SslHandler when it's used in LazyChannelPromise. In SslHandler, this.ctx is only ever set in handlerAdded, which is called via an EventExcecutor (so not necessarily called before syncUninterruptibly() is called).

A slight delay in com.impossibl.postgres.protocol.v30.ProtocolFactoryImpl seems to prevent this exception:

Thread.sleep(10);
sslHandler.handshakeFuture().syncUninterruptibly();

(This is obviously not the correct way to fix this, but this seems to confirm the cause of the problem.)

harbulot commented 9 years ago

I should add that I haven't been able to reproduce the problem when the client is running on a Linux machine, but I'm able to reproduce it regularly from a Windows machine. Both were running the latest Oracle Java 8 release.

mgaido91 commented 9 years ago

I'm running the client from an Android emulator, thus it seems that only linux machines are supported...

kdubb commented 9 years ago

@normanmaurer is @harbulot issue/solution a Netty problem or are we initializing it incorrectly?

jesperpedersen commented 9 years ago

@harbulot Did you report this to the Netty project ?

normanmaurer commented 9 years ago

Let me check if there is a bug in netty

normanmaurer commented 9 years ago

@jesperpedersen @harbulot @kdubb it is a netty bug... Let me fix it there

jesperpedersen commented 9 years ago

@normanmaurer Thanks !

normanmaurer commented 9 years ago

Fixed https://github.com/netty/netty/pull/3868. Will be part of netty 4.0.29.Final

kdubb commented 8 years ago

Fixed by upgrade to Netty