簡體   English   中英

如何將scala play應用程序連接到postgres數據庫

[英]How can I connect a scala play application to postgres database

我正在嘗試將基本播放應用程序連接到我的遠程postgres數據庫。 在克服了幾面牆之后,我現在在連接時遇到了一個看似無法解釋的異常。 該應用程序僅比“activator new”創建的應用程序更多。

TL;博士

在Play應用程序中創建數據庫時,會拋出異常:

[ClassNotFoundException: slick.jdbc.hikaricp.HikariCPJdbcDataSource$]

細節

這是我簡單的application.scala

package controllers

import play.api._
import play.api.mvc._
import play.api.Logger
import slick.jdbc.JdbcBackend.Database

class Application extends Controller {

  def index = Action {
    testdb()
    Ok(views.html.index("Your new application is ready."))
  }

  def testdb(): Unit = {
    val db = Database.forConfig("db.local")
  }
}

我的build.sbt

name := """elophant"""

version := "0.0.1"

lazy val root = (project in file(".")).enablePlugins(PlayScala)

scalaVersion := "2.11.6"

libraryDependencies ++= Seq(
  jdbc,
  cache,
  ws,
  specs2 % Test,
  "org.postgresql" % "postgresql" % "9.4-1204-jdbc4",
  "com.zaxxer" % "HikariCP" % "2.4.1",
  "com.typesafe.slick" %% "slick" % "3.1.0",
  "org.slf4j" % "slf4j-nop" % "1.6.4"
)

resolvers += "scalaz-bintray" at "http://dl.bintray.com/scalaz/releases"

routesGenerator := InjectedRoutesGenerator

application.conf

play.crypto.secret = "xxx"
play.i18n.langs = [ "en" ]

db.local.driver: org.postgresql.Driver
db.local.url="jdbc:postgresql://"${?ELOPHANT_GATEWAY}":xxx/elophant"
db.local.username=elophantuser
db.local.password=${?ELOPHANT_USER_PASSWORD}

(注意:我確認上面的環境變量都設置正確)

但是當我點擊索引操作時,我得到以下異常:

[info] - application - Creating Pool for datasource 'local'
[info] - play.api.db.DefaultDBApi - Database [local] connected at jdbc:postgresql://174.1.53.209:19213/elophant
[info] - play.api.Play - Application started (Dev)
[error] - application -

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

play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[ClassNotFoundException: slick.jdbc.hikaricp.HikariCPJdbcDataSource$]]
    at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:265) ~[play_2.11-2.4.3.jar:2.4.3]
    at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:191) ~[play_2.11-2.4.3.jar:2.4.3]
    at play.api.GlobalSettings$class.onError(GlobalSettings.scala:179) [play_2.11-2.4.3.jar:2.4.3]
    at play.api.DefaultGlobal$.onError(GlobalSettings.scala:212) [play_2.11-2.4.3.jar:2.4.3]
    at play.api.http.GlobalSettingsHttpErrorHandler.onServerError(HttpErrorHandler.scala:94) [play_2.11-2.4.3.jar:2.4.3]
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$9$$anonfun$apply$1.applyOrElse(PlayDefaultUpstreamHandler.scala:158) [play-netty-server_2.11-2.4.3.jar:2.4.3]
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$9$$anonfun$apply$1.applyOrElse(PlayDefaultUpstreamHandler.scala:155) [play-netty-server_2.11-2.4.3.jar:2.4.3]
    at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:36) [scala-library-2.11.6.jar:na]
    at scala.util.Failure$$anonfun$recover$1.apply(Try.scala:215) [scala-library-2.11.6.jar:na]
    at scala.util.Try$.apply(Try.scala:191) [scala-library-2.11.6.jar:na]
    at scala.util.Failure.recover(Try.scala:215) [scala-library-2.11.6.jar:na]
    at scala.concurrent.Future$$anonfun$recover$1.apply(Future.scala:324) [scala-library-2.11.6.jar:na]
    at scala.concurrent.Future$$anonfun$recover$1.apply(Future.scala:324) [scala-library-2.11.6.jar:na]
    at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32) [scala-library-2.11.6.jar:na]
    at play.api.libs.iteratee.Execution$trampoline$.executeScheduled(Execution.scala:109) [play-iteratees_2.11-2.4.3.jar:2.4.3]
    at play.api.libs.iteratee.Execution$trampoline$.execute(Execution.scala:71) [play-iteratees_2.11-2.4.3.jar:2.4.3]
    at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:40) [scala-library-2.11.6.jar:na]
    at scala.concurrent.impl.Promise$DefaultPromise.tryComplete(Promise.scala:248) [scala-library-2.11.6.jar:na]
    at scala.concurrent.Promise$class.complete(Promise.scala:55) [scala-library-2.11.6.jar:na]
    at scala.concurrent.impl.Promise$DefaultPromise.complete(Promise.scala:153) [scala-library-2.11.6.jar:na]
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:23) [scala-library-2.11.6.jar:na]
    at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:40) [akka-actor_2.11-2.3.13.jar:na]
    at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:397) [akka-actor_2.11-2.3.13.jar:na]
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) [scala-library-2.11.6.jar:na]
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) [scala-library-2.11.6.jar:na]
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) [scala-library-2.11.6.jar:na]
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) [scala-library-2.11.6.jar:na]
Caused by: java.lang.ClassNotFoundException: slick.jdbc.hikaricp.HikariCPJdbcDataSource$
    at java.lang.ClassLoader.findClass(ClassLoader.java:530) ~[na:1.8.0_60]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_60]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_60]
    at slick.util.ClassLoaderUtil$$anon$1.loadClass(ClassLoaderUtil.scala:12) ~[slick_2.11-3.1.0.jar:na]
    at slick.jdbc.JdbcDataSource$.loadFactory$1(JdbcDataSource.scala:30) ~[slick_2.11-3.1.0.jar:na]
    at slick.jdbc.JdbcDataSource$.forConfig(JdbcDataSource.scala:35) ~[slick_2.11-3.1.0.jar:na]
    at slick.jdbc.JdbcBackend$DatabaseFactoryDef$class.forConfig(JdbcBackend.scala:268) ~[slick_2.11-3.1.0.jar:na]
    at slick.jdbc.JdbcBackend$$anon$3.forConfig(JdbcBackend.scala:33) ~[slick_2.11-3.1.0.jar:na]
    at controllers.Application.testdb(Application.scala:17) ~[classes/:na]
    at controllers.Application$$anonfun$index$1.apply(Application.scala:11) ~[classes/:na]
    at controllers.Application$$anonfun$index$1.apply(Application.scala:10) ~[classes/:na]
    at play.api.mvc.ActionBuilder$$anonfun$apply$17.apply(Action.scala:439) ~[play_2.11-2.4.3.jar:2.4.3]
    at play.api.mvc.ActionBuilder$$anonfun$apply$17.apply(Action.scala:439) ~[play_2.11-2.4.3.jar:2.4.3]
    at play.api.mvc.ActionBuilder$$anonfun$apply$16.apply(Action.scala:408) ~[play_2.11-2.4.3.jar:2.4.3]
    at play.api.mvc.ActionBuilder$$anonfun$apply$16.apply(Action.scala:407) ~[play_2.11-2.4.3.jar:2.4.3]
    at play.api.mvc.Action$.invokeBlock(Action.scala:533) ~[play_2.11-2.4.3.jar:2.4.3]
    at play.api.mvc.Action$.invokeBlock(Action.scala:530) ~[play_2.11-2.4.3.jar:2.4.3]
    at play.api.mvc.ActionBuilder$$anon$1.apply(Action.scala:493) ~[play_2.11-2.4.3.jar:2.4.3]
    at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$4$$anonfun$apply$5.apply(Action.scala:105) ~[play_2.11-2.4.3.jar:2.4.3]
    at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$4$$anonfun$apply$5.apply(Action.scala:105) ~[play_2.11-2.4.3.jar:2.4.3]
    at play.utils.Threads$.withContextClassLoader(Threads.scala:21) ~[play_2.11-2.4.3.jar:2.4.3]
    at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$4.apply(Action.scala:104) ~[play_2.11-2.4.3.jar:2.4.3]
    at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$4.apply(Action.scala:103) ~[play_2.11-2.4.3.jar:2.4.3]
    at scala.Option.map(Option.scala:146) ~[scala-library-2.11.6.jar:na]
    at play.api.mvc.Action$$anonfun$apply$1.apply(Action.scala:103) ~[play_2.11-2.4.3.jar:2.4.3]
    at play.api.mvc.Action$$anonfun$apply$1.apply(Action.scala:96) ~[play_2.11-2.4.3.jar:2.4.3]
    at play.api.libs.iteratee.DoneIteratee$$anonfun$mapM$2.apply(Iteratee.scala:741) ~[play-iteratees_2.11-2.4.3.jar:2.4.3]
    at play.api.libs.iteratee.DoneIteratee$$anonfun$mapM$2.apply(Iteratee.scala:741) ~[play-iteratees_2.11-2.4.3.jar:2.4.3]
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24) [scala-library-2.11.6.jar:na]
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24) [scala-library-2.11.6.jar:na]
    ... 6 common frames omitted

一些谷歌搜索建議我在我的build.sbt中包含hikari庫,但它似乎沒有幫助(同樣,它不在任何游戲本身的文檔中)。

我的java配置技能可以忽略不計,所以任何幫助都將不勝感激!

我設法解決了它。 經過一番搜索后,我偶然發現了一個更現代的光滑/ postgres教程(順便說一下,這似乎是一個非常有用的博客文章,任何人試圖設置一個光滑+ postgres播放應用程序):

以下是帖子的鏈接:

https://stonecolddev.in/posts/playing-with-scala-building-a-small-web-app-with-play-2-4-play-slick-and-postgres.html

結果,我將這兩個庫添加到build.sbt中:

"com.typesafe.play" %% "play-slick" % "1.1.0",
"com.typesafe.play" %% "play-slick-evolutions" % "1.1.0"

這導致我的異常改為:

play.api.UnexpectedException: Unexpected exception[CreationException: Unable to create injector, see the following errors:

1) A binding to play.api.db.DBApi was already configured at play.api.db.slick.evolutions.EvolutionsModule.bindings(EvolutionsModule.scala:15):
Binding(interface play.api.db.DBApi to ConstructionTarget(class play.api.db.slick.evolutions.internal.DBApiAdapter) in interface javax.inject.Singleton) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1).
  at play.api.db.DBModule.bindings(DBModule.scala:25):
Binding(interface play.api.db.DBApi to ProviderConstructionTarget(class play.api.db.DBApiProvider)) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)

1 error]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(DevServerStart.scala:165) ~[play-server_2.11-2.4.3.jar:2.4.3]
    ...

幸運的是,這個錯誤更常見,一些快速的谷歌搜索證實了我的預感 - 我有一個包含多次的庫。 谷歌想出了:

https://groups.google.com/forum/#!topic/play-framework/NOFbfx13fio

Mirco Dotta的回答表明jdbc正在被多次包含,並且看哪,從我的build.sbt中刪除它解決了這個問題:

libraryDependencies ++= Seq(
  jdbc,  # Remove this
  cache,
  ws,
  specs2 % Test,
  "org.postgresql" % "postgresql" % "9.4-1204-jdbc4",
  "com.typesafe.play" %% "play-slick" % "1.1.0",
  "com.typesafe.play" %% "play-slick-evolutions" % "1.1.0",
  "com.typesafe.slick" %% "slick" % "3.1.0",
  "org.slf4j" % "slf4j-nop" % "1.6.4"
)

注意 :jdbc被激活器的項目生成器自動放入其中,這使得它更容易被遺漏。

注意2 :對於沒有解決問題的任何人,stonecolddev博客文章還建議他有連接問題,通過在他的application.conf中添加以下內容來解決:

slick.dbs.default.driver="slick.driver.PostgresDriver$"
slick.dbs.default.db.driver="org.postgresql.Driver"

注3 :Hikaricp庫不需要包含在內,因為它是從版本2.4開始構建的。 這就是官方文檔沒有提到它的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM