这是一个错误吗?
我正在使用Play框架2.6.6和scala 2.12.3。我在application.conf中定义了3个数据库(hikaricp连接池的设置遍布地图,因为我尝试了它们):
db {
mentions {
driver="org.postgresql.Driver"
url="jdbc:postgresql://localhost:5432/mentions"
password="***"
username="play"
hikaricp {
maximumPoolSize = 2
minimumIdle=2
}
}
postgres {
driver="org.postgresql.Driver"
url="jdbc:postgresql://localhost:5432/postgres"
password="***"
username="postgres"
hikaricp {
maximumPoolSize = 9
minimumIdle=9
}
}
sqlserver {
driver="net.sourceforge.jtds.jdbc.Driver"
url="jdbc:jtds:sqlserver://10.211.55.5:1433/db"
username="sa"
password="***"
hikaricp {
maximumPoolSize=4
minimumIdle=4
//connectionTestQuery="select 1"
}
}
}
使用此配置,Hikaricp连接池无法初始化sql server连接池,实际上没有其他两个连接池被初始化。修复sql server连接错误的方法是设置connectionTestQuery。这不是这篇文章的重点。我不明白为什么其他两个连接失败时会失败。在我看来,其他两个连接池仍应运行。
以下是来自控制台的错误消息:
[info] application - Creating Pool for datasource 'sqlserver'
[error] c.z.h.p.PoolBase - HikariPool-1 - Failed to execute isValid() for connection, configure connection test query (null).
[info] application - Creating Pool for datasource 'sqlserver'
[error] c.z.h.p.PoolBase - HikariPool-2 - Failed to execute isValid() for connection, configure connection test query (null).
[info] application - Creating Pool for datasource 'sqlserver'
[error] c.z.h.p.PoolBase - HikariPool-3 - Failed to execute isValid() for connection, configure connection test query (null).
[error] application -
! @761fipg95 - Internal server error, for (GET) [/] ->
play.api.UnexpectedException: Unexpected exception[CreationException: Unable to create injector, see the following errors:
1) Error injecting method, java.lang.AbstractMethodError
at com.google.inject.util.Providers$GuicifiedProviderWithDependencies.initialize(Providers.java:149)
at play.api.db.DBModule$$anonfun$$lessinit$greater$1.$anonfun$new$1(DBModule.scala:25):
Binding(interface play.api.db.Database qualified with QualifierInstance(@play.db.NamedDatabase(value=sqlserver)) to ProviderTarget(play.api.db.NamedDatabaseProvider@65c05a8b)) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
2) Error injecting method, java.lang.AbstractMethodError
at com.google.inject.util.Providers$GuicifiedProviderWithDependencies.initialize(Providers.java:149)
at play.api.db.DBModule$$anonfun$$lessinit$greater$1.$anonfun$new$1(DBModule.scala:25):
Binding(interface play.api.db.Database qualified with QualifierInstance(@play.db.NamedDatabase(value=mentions)) to ProviderTarget(play.api.db.NamedDatabaseProvider@700c1d35)) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
3) Error injecting method, java.lang.AbstractMethodError
at com.google.inject.util.Providers$GuicifiedProviderWithDependencies.initialize(Providers.java:149)
at play.api.db.DBModule$$anonfun$$lessinit$greater$1.$anonfun$new$1(DBModule.scala:25):
Binding(interface play.api.db.Database qualified with QualifierInstance(@play.db.NamedDatabase(value=postgres)) to ProviderTarget(play.api.db.NamedDatabaseProvider@1f4f0047)) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
3 errors]
at play.core.server.DevServerStart$$anon$1.reload(DevServerStart.scala:186)
at play.core.server.DevServerStart$$anon$1.get(DevServerStart.scala:124)
at play.core.server.AkkaHttpServer.modelConversion(AkkaHttpServer.scala:183)
at play.core.server.AkkaHttpServer.handleRequest(AkkaHttpServer.scala:189)
at play.core.server.AkkaHttpServer.$anonfun$createServerBinding$3(AkkaHttpServer.scala:106)
at akka.stream.impl.fusing.MapAsync$$anon$23.onPush(Ops.scala:1172)
at akka.stream.impl.fusing.GraphInterpreter.processPush(GraphInterpreter.scala:499)
at akka.stream.impl.fusing.GraphInterpreter.processEvent(GraphInterpreter.scala:462)
at akka.stream.impl.fusing.GraphInterpreter.execute(GraphInterpreter.scala:368)
at akka.stream.impl.fusing.GraphInterpreterShell.runBatch(ActorGraphInterpreter.scala:571)
Caused by: com.google.inject.CreationException: Unable to create injector, see the following errors:
1) Error injecting method, java.lang.AbstractMethodError
at com.google.inject.util.Providers$GuicifiedProviderWithDependencies.initialize(Providers.java:149)
at play.api.db.DBModule$$anonfun$$lessinit$greater$1.$anonfun$new$1(DBModule.scala:25):
Binding(interface play.api.db.Database qualified with QualifierInstance(@play.db.NamedDatabase(value=sqlserver)) to ProviderTarget(play.api.db.NamedDatabaseProvider@65c05a8b)) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
2) Error injecting method, java.lang.AbstractMethodError
at com.google.inject.util.Providers$GuicifiedProviderWithDependencies.initialize(Providers.java:149)
at play.api.db.DBModule$$anonfun$$lessinit$greater$1.$anonfun$new$1(DBModule.scala:25):
Binding(interface play.api.db.Database qualified with QualifierInstance(@play.db.NamedDatabase(value=mentions)) to ProviderTarget(play.api.db.NamedDatabaseProvider@700c1d35)) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
3) Error injecting method, java.lang.AbstractMethodError
at com.google.inject.util.Providers$GuicifiedProviderWithDependencies.initialize(Providers.java:149)
at play.api.db.DBModule$$anonfun$$lessinit$greater$1.$anonfun$new$1(DBModule.scala:25):
Binding(interface play.api.db.Database qualified with QualifierInstance(@play.db.NamedDatabase(value=postgres)) to ProviderTarget(play.api.db.NamedDatabaseProvider@1f4f0047)) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
3 errors
at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:470)
at com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:176)
at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:110)
at com.google.inject.Guice.createInjector(Guice.java:99)
at com.google.inject.Guice.createInjector(Guice.java:84)
at play.api.inject.guice.GuiceBuilder.injector(GuiceInjectorBuilder.scala:185)
at play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:137)
at play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21)
at play.core.server.DevServerStart$$anon$1.$anonfun$reload$3(DevServerStart.scala:174)
at play.utils.Threads$.withContextClassLoader(Threads.scala:21)
Caused by: java.lang.AbstractMethodError: null
at net.sourceforge.jtds.jdbc.JtdsConnection.isValid(JtdsConnection.java:2833)
at com.zaxxer.hikari.pool.PoolBase.checkDriverSupport(PoolBase.java:456)
at com.zaxxer.hikari.pool.PoolBase.setupConnection(PoolBase.java:423)
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:381)
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:205)
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:448)
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:519)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:113)
at com.zaxxer.hikari.HikariDataSource.<init>(HikariDataSource.java:72)
at play.api.db.HikariCPConnectionPool.$anonfun$create$1(HikariCPModule.scala:51)
更新:我仍然认为在架构上,如果一个连接池不起作用,其他连接池不应受到影响。今天我关闭运行sql server的windows vm,我只运行了postgresql服务器。我测试的页面只连接到postgresql dbs,它仍然失败,因为sql server连接池没有工作。这次失败了,配置错误java.sql.SQLException - Login Timed out。
答案 0 :(得分:0)
在2.6.6&amp;进行一些调试后2.6.7,我发现了以下内容:
java.lang.AbstractMethodError继承继承java.lang.LinkageError的java.lang.IncompatibleClassChangeError。根据NonFatal对象,java.lang.LinkageError被视为致命错误:
object NonFatal {
/**
* Returns true if the provided `Throwable` is to be considered non-fatal, or false if it is to be considered fatal
*/
def apply(t: Throwable): Boolean = t match {
// VirtualMachineError includes OutOfMemoryError and other fatal errors
case _: VirtualMachineError | _: ThreadDeath | _: InterruptedException | _: LinkageError | _: ControlThrowable => false
case _ => true
}
/**
* Returns Some(t) if NonFatal(t) == true, otherwise None
*/
def unapply(t: Throwable): Option[Throwable] = if (apply(t)) Some(t) else None
}
因此,遍布代码的Try调用不会捕获此异常。
异常最终由guice图层处理。该调用返回到guice Initializer.injectAll方法,该方法(以及其他对象)为application.conf文件中配置的每个数据库连接注入NamedDatabaseProvider对象(与DBModule连接到NamedDatabaseProvider的绑定)。 NamedDatabaseProvider对象依赖于DBApi,由于AbstractMethodError异常被认为是致命的,因此每次初始化都会失败。
最终问题是情况的组合:1。Hikaricp代码中的异常抛出是致命的,2。DBApi代码想要初始化所有连接池并且它不会处理致命错误。
我不认为这是一个错误。也许Hickaricp家伙可能会抛出UnsupportedOperationException或similar。
对于其他感兴趣的人,我发现了这个:https://github.com/njlg/playdb。