2017-11-12 1 views
0

Ist es ein Fehler?Alle Verbindungspools können nicht initialisiert werden, wenn ein Verbindungspool nicht initialisiert werden kann

Ich benutze Playframework 2.6.6 mit Scala 2.12.3. Ich habe 3 Datenbanken in application.conf definiert (die Einstellungen für die hikaricp Verbindungspools sind über die ganze Karte, weil ich mit ihnen experimentiert):

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" 
    } 
    } 

} 

Mit dieser Konfiguration ist der Hikaricp Verbindungspool nicht die SQL-Server-Verbindung zu initialisieren Pool und tatsächlich wird keiner der anderen zwei Verbindungspools initialisiert. Die Fehlerbehebung für den SQL Server-Verbindungsfehler besteht darin, die connectionTestQuery festzulegen. Das ist nicht der Sinn dieses Posts. Ich verstehe nicht, warum die anderen zwei Verbindungen fehlschlagen, wenn diese fehlschlägt. Meiner Meinung nach sollten die anderen zwei Verbindungspools immer noch funktionieren.

Hier sind die Fehlermeldungen von der Konsole:

[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([email protected])) (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([email protected])) (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([email protected])) (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([email protected])) (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([email protected])) (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([email protected])) (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) 

Ein Update: Ich denke immer noch, dass architektonisch, wenn ein Verbindungspool nicht funktioniert, die anderen Verbindungen Pools sollten nicht betroffen sein. Heute habe ich meinen Windows vm running sql server heruntergefahren und ich hatte nur meinen postgresql server laufen. Die Seite, die ich getestet habe, ist nur mit den postgresql-dbs verbunden und es ist immer noch fehlgeschlagen, weil der SQL Server-Verbindungspool nicht funktioniert hat. Diesmal ist es mit einem Konfigurationsfehler java.sql.SQLException - Login Timing fehlgeschlagen.

Antwort

0

Nachdem einige Debug in 2.6.6 & 2.6.7 tun, entdeckte ich folgendes:

java.lang.AbstractMethodError erbt java.lang.IncompatibleClassChangeError die java.lang.LinkageError erbt. java.lang.LinkageError ist fatal betrachtet nach dem nonfatal Objekt:

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 
} 

So ist die Try Anrufe auf dem ganzen Code bestreut nicht diese Ausnahme abfangen.

Die Ausnahme wird von den GUICE-Layern behandelt. Der Aufruf geht zurück zur Methode guitice Initializer.injectAll, die (unter anderen Objekten) die NamedDatabaseProvider-Objekte für jede in der Datei application.conf konfigurierte Datenbankverbindung einfügt (die Bindung an den NamedDatabaseProvider ist im DBModule verdrahtet). Die NamedDatabaseProvider-Objekte hängen von DBApi ab, dessen Initialisierung jedes Mal aufgrund der Ausnahme "AbstractMethodError" fehlschlägt, die als "fatal" betrachtet wird. Das Problem ist letztendlich eine Kombination von Umständen: 1. Die Ausnahme, die den Hikaricp-Code auslöst, ist fatal, 2. Der DBApi-Code möchte alle Verbindungspools initialisieren und behandelt keine fatalen Fehler.

Ich halte dies nicht für einen Fehler. Vielleicht hätten die Hickaricp-Typen eine UnsupportedOperationException oder etwas similar ausgelöst.

Für andere interessierte ich fand dies: https://github.com/njlg/playdb.

Verwandte Themen