2013-06-11 3 views
16

Sto scrivendo un'app web Scala utilizzando Play Framework 2.1.1 utilizzando un database Postgres locale insieme a Slick 1.0.0 e mi sto imbattendo in quella che sembra essere una contraddizione qui.Perché l'azione di riproduzione fallisce con "nessun driver adatto trovato" con Slick e PostgreSQL?

Questo è l'errore che sto funzionando in:

[SQLException: No suitable driver found for postgres://user:[email protected]:5432/postgres] 
56 
57 def instance = Action { 
58 Database.forURL("postgres://user:[email protected]:5432/postgres", driver = "org.postgresql.Driver") withSession { 
59  val q = Retailer.map(_.name) 
60  Ok(views.html.instance(q.list, newRForm)) 
61 } 
62 } 
63 

Dove user e password sono rispettivamente il username e password del database Postgres.

In java error (No suitable driver found) ho trovato:

  1. Avrai bisogno di caricare il driver da qualche parte con Class.forName("org.postgresql.Driver");
  2. Avrete bisogno di file jar del driver PostgreSQL nel classpath del programma.

In Application.scala Ho il seguente blocco di codice:

{ 
    println(ConfigFactory.load().getString("db.default.url")) 
    println(Class.forName("org.postgresql.Driver")) 
} 

Riesecuzione play compile risultati in:

(Server started, use Ctrl+D to stop and go back to the console...) 

[info] play - database [default] connected at jdbc:postgresql://localhost:5432/postgres 
[info] play - Application started (Dev) 
postgres://user:[email protected]:5432/postgres 
class org.postgresql.Driver 
[error] application - 

! @6ei1nhkop - Internal server error, for (GET) [/instance] -> 

play.api.Application$$anon$1: Execution exception[[SQLException: No suitable driver found for jdbc:postgresql://user:[email protected]:5432/postgres]] 
     at play.api.Application$class.handleError(Application.scala:289) ~[play_2.10.jar:2.1.1] 
     at play.api.DefaultApplication.handleError(Application.scala:383) [play_2.10.jar:2.1.1] 
     at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$17$$anonfun$apply$24.apply(PlayDefaultUpstreamHandler.scala:326) [play_2.10.jar:2.1.1] 
     at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$17$$anonfun$apply$24.apply(PlayDefaultUpstreamHandler.scala:324) [play_2.10.jar:2.1.1] 
     at play.api.libs.concurrent.PlayPromise$$anonfun$extend1$1.apply(Promise.scala:113) [play_2.10.jar:2.1.1] 
     at play.api.libs.concurrent.PlayPromise$$anonfun$extend1$1.apply(Promise.scala:113) [play_2.10.jar:2.1.1] 
java.sql.SQLException: No suitable driver found for jdbc:postgresql://user:[email protected]:5432/postgres 
     at java.sql.DriverManager.getConnection(Unknown Source) ~[na:1.7.0_21] 
     at java.sql.DriverManager.getConnection(Unknown Source) ~[na:1.7.0_21] 
     at scala.slick.session.Database$$anon$2.createConnection(Database.scala:105) ~[slick_2.10-1.0.0.jar:1.0.0] 
     at scala.slick.session.BaseSession.conn$lzycompute(Session.scala:207) ~[slick_2.10-1.0.0.jar:1.0.0] 
     at scala.slick.session.BaseSession.conn(Session.scala:207) ~[slick_2.10-1.0.0.jar:1.0.0] 
     at scala.slick.session.BaseSession.close(Session.scala:221) ~[slick_2.10-1.0.0.jar:1.0.0] 

Poi corro play dependencies ei postgres .jar si risolve!

Here are the resolved dependencies of your application: 
+--------------------------------------------------------+--------------------------------------------------------+-----------------------------------+ 
| ←[32mpostgresql:postgresql:9.1-901-1.jdbc4←[0m   | ←[37mats:ats_2.10:1.0-SNAPSHOT←[0m      | ←[37mAs postgresql-9.1-901-1.jdbc4.jar←[0m | 
+--------------------------------------------------------+--------------------------------------------------------+-----------------------------------+ 

Perché non è possibile trovare un driver adatto?

conf/application.conf

# Database configuration 
db.default.driver=org.postgresql.Driver 
db.default.url="jdbc:postgres://user:[email protected]:5432/postgres" 
db.default.user=user  
db.default.password=password 

progetto/Build.scala

import sbt._ 
import Keys._ 
import play.Project._ 

object ApplicationBuild extends Build { 

    val appName = "ats" 
    val appVersion = "1.0-SNAPSHOT" 

    val appDependencies = Seq(
    // Add your project dependencies here, 
    jdbc, 
    "com.typesafe.slick" %% "slick"  % "1.0.0", 
    "postgresql"   % "postgresql" % "9.1-901-1.jdbc4" 
) 

    val main = play.Project(appName, appVersion, appDependencies).settings(
    // Add your own project settings here  
) 

ho anche postgresql-9.2-1002.jdbc4.jar e slick_2.10-1.0.1-RC1.jar nel mio file /lib, e la mia versione locale Postgres da fare a SELECT version(); è 9.2.4 La risoluzione del driver postgres sembra essere risolvendo comunque il 9.1 .jar, e quando commento la dipendenza dell'app per consentire a /lib di essere incluso da solo, /lib non sembra essere sul CLASSPATH di Play.

So che l'URL di Postgres è corretto e sono in grado di connettersi al mio database quando la mia applicazione viene avviata per la prima volta.

risposta

16

Stai mescolando le cose.

Allora ho guardato a questa domanda che dice ...

  1. Avrai bisogno di caricare il driver da qualche parte. Class.forName ("org.postgresql.Driver");
  2. È necessario il file .jar del driver postgresql nel classpath del programma.

Questo non è applicabile in questo caso. Hai una struttura che si prende cura di queste cose per te. La domanda a cui fai riferimento sta descrivendo come accedere a un database con jdbc "raw".


Ecco come si dovrebbe fare.

Prima di tutto è possibile semplificare la parte di configurazione. 5432 è la porta predefinita per postresql e localhost è anche l'host predefinito. Nome utente e password devono essere posizionati all'esterno dell'URL.

# Database configuration 
db.default.driver=org.postgresql.Driver 
db.default.url=jdbc:postgres:postgres 
db.default.user=user  
db.default.password=password 

Definire ora le dipendenze sbt corrette. È sufficiente rimuovere i file jar dalla cartella /lib e aggiornare le dipendenze per ottenere l'ultimo driver PostgreSQL (9.2) modificando l'AppDependencies Build.scala. Tieni presente che il groupId è stato modificato da postgresql a org.postgresql.

val appDependencies = Seq(
    // Add your project dependencies here, 
    jdbc, 
    "com.typesafe.slick" %% "slick" % "1.0.0", 
    "org.postgresql" % "postgresql" % "9.3-1102-jdbc41" 
) 

E infine si dovrebbe cambiare il controller per risolvere l'origine dati dalla configurazione:

def instance = Action { 
    Database.forDataSource(DB.getDataSource()) withSession { 
    val q = Retailer.map(_.name) 
    Ok(views.html.instance(q.list, newRForm)) 
    } 
} 
+0

Hum. forURL vs forDataSource è come driver vs datasource in jdbc [http://fernandezpablo85.github.io/2013/04/07/slick_connection_pooling.html] – Meredith