Почему действие "Действие" завершилось неудачей с "не найденным подходящим драйвером" с помощью Slick и PostgreSQL?

Я пишу веб-приложение Scala, используя Play Framework 2.1.1, используя локальную базу данных Postgres вместе с Slick 1.0.0, и я сталкиваюсь с тем, что кажется противоречием здесь.

Это ошибка, с которой я столкнулся:

[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

Где user и password являются соответственно username и password базы данных Postgres.

В java error (Не найдено подходящего драйвера) Я нашел:

  • Вам нужно будет загрузить драйвер где-нибудь с помощью Class.forName("org.postgresql.Driver");
  • Вам понадобится файл jar файла PostgreSQL в пути к вашей программе.

В Application.scala У меня есть следующий код:

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

Rerunning play compile приводит к:

(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]

Затем я запустил play dependencies, и postgres.jar разрешен!

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 |
+--------------------------------------------------------+--------------------------------------------------------+-----------------------------------+

Почему не может быть найден подходящий драйвер?

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

Проект /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    
  )

У меня также есть postgresql-9.2-1002.jdbc4.jar и slick_2.10-1.0.1-RC1.jar в моем файле /lib, а моя локальная версия Postgres от SELECT version(); 9.2.4. Разрешение драйвера postgres, кажется, разрешает к 9.1.jar, хотя, и когда я прокомментирую зависимость приложения, чтобы /lib был включен сам по себе, /lib, похоже, не включен в Play CLASSPATH.

Я знаю, что URL-адрес Postgres верен, и я могу подключиться к моей базе данных, когда мое приложение запускается впервые.

Ответы

Ответ 1

Вы смешиваете вещи.

Итак, я посмотрел на этот вопрос, который говорит...

  • Вам нужно будет загрузить драйвер где-нибудь. Class.forName( "org.postgresql.Driver" );
  • Вам понадобится файл .jar драйвера postgresql в пути к вашей программе.

В этом случае это неприменимо. У вас есть структура, которая заботится об этих вещах для вас. Этот вопрос, на который вы ссылаетесь, описывает, как получить доступ к базе данных с помощью "raw" jdbc.


Вот как вы должны это делать.

Прежде всего, вы можете упростить конфигурационную часть. 5432 - это порт по умолчанию для postresql, а localhost также является хостом по умолчанию. Имя пользователя и пароль должны быть размещены вне URL-адреса.

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

Теперь определите правильные зависимости sbt. Просто удалите файлы jar из папки /lib и обновите свои зависимости, чтобы получить последний драйвер PostgreSQL (9.2), изменив ваши приложения Build.scala appDependencies. Имейте в виду, что groupId изменился с postgresql на 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"
)

И, наконец, вы должны изменить свой контроллер, чтобы разрешить источник данных из конфигурации:

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