在 Java 15 中,使用来自 jdbc.postgresql.org 的 PostgreSQL JDBC 驱动程序(版本 42.2.18,JDBC4.2)以及以下
DataSource
:
PGSimpleDataSource ds = new PGSimpleDataSource();
ds.setServerNames( new String[] { "my-server-address" } );
ds.setPortNumbers( new int[] { 25060 } );
ds.setSsl( true );
ds.setDatabaseName( "mydb" );
ds.setUser( "scott" );
ds.setPassword( "tiger" );
this.dataSource = ds;
…代码
Connection conn = this.dataSource.getConnection();
抛出此异常:
org.postgresql.util.PSQLException:无法打开 SSL 根证书文件 /Users/basilbourque/.postgresql/root.crt。
我知道我的 Postgres 12 服务器已设置为 SSL 连接,因为我的 IntelliJ Ultimate 具有数据库访问功能 (DataGrip),可以成功连接 SSL (TLS) 保护。
那么我的 JDBC
DataSource
配置有什么问题吗?
感谢 this Github issues pgjdbc 驱动程序页面,我找到了 davecramer 的这篇文章:
从 42.2.5 开始,ssl=true 意味着按照发行说明进行验证。如果您希望获得旧行为,请使用 sslmode=require
果然,将
ds.setSsl( true );
替换为 ds.setSslMode( "require" );
允许我的 JDBC 驱动程序通过 DataSource
进行连接。
PGSimpleDataSource ds = new PGSimpleDataSource();
ds.setServerNames( new String[] { "my-server-address" } );
ds.setPortNumbers( new int[] { 25060 } );
ds.setSslMode( "require" ); // Replaces: ds.setSsl( true );
ds.setDatabaseName( "mydb" );
ds.setUser( "scott" );
ds.setPassword( "tiger" );
this.dataSource = ds;
我不知道这些 SSL/TLS 相关选项实际上在做什么,但这对我来说可以连接到我的 DigitalOcean 管理的 Postgres 数据库服务器。
以下代码片段现已成功运行:
try
(
Connection conn = this.dataSource.getConnection() ;
Statement stmt = conn.createStatement() ;
)
{
String sql =
"""
SELECT uuid_generate_v1()
;
""";
try (
ResultSet rs = stmt.executeQuery( sql ) ;
)
{
while ( rs.next() )
{
UUID uuid = rs.getObject( 1 , UUID.class );
System.out.println( "uuid = " + uuid );
}
}
}
catch ( SQLException e )
{
e.printStackTrace();
}
对于在 Google 上搜索错误消息的人,还要考虑您是否打算使用 SSL 连接。当我打算使用“SSH 隧道”时,我在 DBeaver 中选中了错误的框。