连接到 Play Framework 上的 as400 JDBC

Connecting to as400 JDBC on Play Framework

我在 Play! 中连接到 AS400 数据库时遇到问题。

我的 application.conf 看起来像:

db.default.driver="com.ibm.as400.access.AS400JDBCDriver"
db.default.url="jdbc:as400://SERVER;libraries=A,B,C;toolbox trace=all;trace=true"
db.default.username="user"
db.default.password="password"

我已经在 class 路径中设置了 jt400,我可以在 "external libraries" 下看到它出现并且可用。但基本上我收到一条关于连接失败的错误消息(在 user/password 我知道有效)并且无法连接到 execute isValid(),这是一个无法在 AS400JDBCConnection [=28] 中找到的函数=].

[error] c.z.h.p.PoolBase - HikariPool-1 - Failed to execute isValid() for connection, configure connection test query. (com.ibm.as400.access.AS400JDBCConnection.isValid(I)Z)
[error] application - 

! @72265nf0a - Internal server error, for (GET) [/] ->

play.api.Configuration$$anon: Configuration error[Cannot connect to database [default]]
    at play.api.Configuration$.configError(Configuration.scala:154)
    at play.api.Configuration.reportError(Configuration.scala:806)
    at play.api.db.DefaultDBApi$$anonfun$connect.apply(DefaultDBApi.scala:48)
    at play.api.db.DefaultDBApi$$anonfun$connect.apply(DefaultDBApi.scala:42)
    at scala.collection.immutable.List.foreach(List.scala:381)
    at play.api.db.DefaultDBApi.connect(DefaultDBApi.scala:42)
    at play.api.db.DBApiProvider.get$lzycompute(DBModule.scala:72)
    at play.api.db.DBApiProvider.get(DBModule.scala:62)
    at play.api.db.DBApiProvider.get(DBModule.scala:58)
    at com.google.inject.internal.ProviderInternalFactory.provision(ProviderInternalFactory.java:81)
Caused by: play.api.Configuration$$anon: Configuration error[Failed to initialize pool: com.ibm.as400.access.AS400JDBCConnection.isValid(I)Z]
    at play.api.Configuration$.configError(Configuration.scala:154)
    at play.api.PlayConfig.reportError(Configuration.scala:996)
    at play.api.db.HikariCPConnectionPool.create(HikariCPModule.scala:70)
    at play.api.db.PooledDatabase.createDataSource(Databases.scala:199)
    at play.api.db.DefaultDatabase.dataSource$lzycompute(Databases.scala:123)
    at play.api.db.DefaultDatabase.dataSource(Databases.scala:121)
    at play.api.db.DefaultDatabase.getConnection(Databases.scala:142)
    at play.api.db.DefaultDatabase.getConnection(Databases.scala:138)
    at play.api.db.DefaultDBApi$$anonfun$connect.apply(DefaultDBApi.scala:44)
    at play.api.db.DefaultDBApi$$anonfun$connect.apply(DefaultDBApi.scala:42)
Caused by: com.zaxxer.hikari.pool.HikariPool$PoolInitializationException: Failed to initialize pool: com.ibm.as400.access.AS400JDBCConnection.isValid(I)Z
    at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:512)
    at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:105)
    at com.zaxxer.hikari.HikariDataSource.<init>(HikariDataSource.java:71)
    at play.api.db.HikariCPConnectionPool$$anonfun.apply(HikariCPModule.scala:58)
    at play.api.db.HikariCPConnectionPool$$anonfun.apply(HikariCPModule.scala:54)
    at scala.util.Try$.apply(Try.scala:192)
    at play.api.db.HikariCPConnectionPool.create(HikariCPModule.scala:54)
    at play.api.db.PooledDatabase.createDataSource(Databases.scala:199)
    at play.api.db.DefaultDatabase.dataSource$lzycompute(Databases.scala:123)
    at play.api.db.DefaultDatabase.dataSource(Databases.scala:121)
Caused by: java.lang.AbstractMethodError: com.ibm.as400.access.AS400JDBCConnection.isValid(I)Z
    at com.zaxxer.hikari.pool.PoolBase.checkDriverSupport(PoolBase.java:400)
    at com.zaxxer.hikari.pool.PoolBase.setupConnection(PoolBase.java:375)
    at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:346)
    at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:506)
    at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:105)
    at com.zaxxer.hikari.HikariDataSource.<init>(HikariDataSource.java:71)
    at play.api.db.HikariCPConnectionPool$$anonfun.apply(HikariCPModule.scala:58)
    at play.api.db.HikariCPConnectionPool$$anonfun.apply(HikariCPModule.scala:54)
    at scala.util.Try$.apply(Try.scala:192)
    at play.api.db.HikariCPConnectionPool.create(HikariCPModule.scala:54)

我可以在其他基于 java 的项目中使用类似以下内容的连接:

try {
                Class.forName("com.ibm.as400.access.AS400JDBCDriver");
                Connection con = DriverManager.getConnection("jdbc:as400://" + 
                    ApplicationAuthentication.server + "/" + 
                    ApplicationAuthentication.library, 
                    ApplicationAuthentication.user, 
                    ApplicationAuthentication.password
                );
            } catch (Exception e) {
                System.err.println(e);
                throw new WebApplicationException(genericError, Response.Status.UNAUTHORIZED);
            }

从堆栈跟踪中猜测,从您的驱动程序返回的连接似乎不能很好地处理连接 Hikari Connection Pool. Hikari is default connection pool in playframework

具体来说,您的异常跟踪显示 Hikari CP 正尝试在您的 JDBC 驱动程序返回的连接对象上调用 isValid 方法,然后失败 java.lang.AbstractMethodError

您可以尝试切换到 BoneCP 连接池,看看是否有帮助。您还可以在 hikari github 问题列表

上查看对 this issue 的评论

尝试将以下内容添加到 application.config

db.default.hikaricp.connectionTestQuery="SELECT 1"

未在 Play Framework 中测试,但我在 spring 框架上遇到了类似的问题并以这种方式解决了。

像下面这样使用 liquibase 数据源 connection-test-query

@Bean
    @LiquibaseDataSource
    public DataSource liquibaseDataSource() {
         HikariDataSource dataSource = (HikariDataSource) DataSourceBuilder.create().url("url")
                        .username("username")
                        .password("password")
                        .type(HikariDataSource.class).build();
        dataSource.setConnectionTestQuery("select 1 from sysibm.sysdummy1");
        return dataSource;
    }