简体   繁体   English

如何将scala play应用程序连接到postgres数据库

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

I'm trying to connect a basic play application to my remote postgres database. 我正在尝试将基本播放应用程序连接到我的远程postgres数据库。 After overcoming a few walls, I'm now stuck on a seemingly unexplained exception when connecting. 在克服了几面墙之后,我现在在连接时遇到了一个看似无法解释的异常。 The application is barely more than that created from "activator new". 该应用程序仅比“activator new”创建的应用程序更多。

tl;dr TL;博士

When creating database in play application, an exception is thrown: 在Play应用程序中创建数据库时,会抛出异常:

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

Details 细节

Here's my simple application.scala : 这是我简单的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")
  }
}

And my build.sbt : 我的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

And application.conf : 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}

(Note: I verified that the above environment variables are all set correctly) (注意:我确认上面的环境变量都设置正确)

But when I hit the index action, I get the following exception: 但是当我点击索引操作时,我得到以下异常:

[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

Some googling suggested that I include that hikari library in my build.sbt, but it hasn't seemed to help (also, it's not in any of the documentation for play itself). 一些谷歌搜索建议我在我的build.sbt中包含hikari库,但它似乎没有帮助(同样,它不在任何游戏本身的文档中)。

My java configuration skills are negligible, so any help would be appreciated! 我的java配置技能可以忽略不计,所以任何帮助都将不胜感激!

I managed to resolve it. 我设法解决了它。 After some searching I stumbled upon a more modern slick/postgres tutorial (incidentally, this seems like a very useful blog post for anyone trying to setup a slick+postgres play app): 经过一番搜索后,我偶然发现了一个更现代的光滑/ postgres教程(顺便说一下,这似乎是一个非常有用的博客文章,任何人试图设置一个光滑+ postgres播放应用程序):

Below is the link to the post : 以下是帖子的链接:

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

As a result, I added these two libraries to my build.sbt: 结果,我将这两个库添加到build.sbt中:

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

This caused my exception to change into this: 这导致我的异常改为:

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

Fortunately this error is a little more common, and some quick googling confirmed my hunch - I had a library included multiple times. 幸运的是,这个错误更常见,一些快速的谷歌搜索证实了我的预感 - 我有一个包含多次的库。 Google came up with: 谷歌想出了:

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

The answer by Mirco Dotta suggests that jdbc is being including multiple times, and lo and behold, removing that from my build.sbt resolved the issue: 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"
)

Note : jdbc was automatically put in there by activator's project generator, which made it easier to miss. 注意 :jdbc被激活器的项目生成器自动放入其中,这使得它更容易被遗漏。

Note 2 : For anyone for whom this doesn't resolve your issue, the stonecolddev blog post also suggests he had connectivity issues which were resolved by adding the following to his application.conf, in this order: 注意2 :对于没有解决问题的任何人,stonecolddev博客文章还建议他有连接问题,通过在他的application.conf中添加以下内容来解决:

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

Note 3 : The Hikaricp library does not need to be included, as it is built into play as of version 2.4. 注3 :Hikaricp库不需要包含在内,因为它是从版本2.4开始构建的。 This is why the official docs don't refer to it. 这就是官方文档没有提到它的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 尝试通过 scala/spark 应用程序连接到 postgres 数据库时出现 ClassNotFoundException - ClassNotFoundException when trying to connect to a postgres database through a scala/spark application 当我遇到超时错误时,如何将 Azure postgres 数据库连接到 pgadmin - How can i connect Azure postgres database to pgadmin as im getting time out error 如何在Scala Mac OS中使用postgres JDBC? - How can I get postgres JDBC working in Scala Mac OS? 如何在Play2 Scala模板中设置所选选项? - How can I set selected option in Play2 scala template? 如何在Java应用程序中播放.SWF? - How can I play .SWF in a Java Application? 无法使用 Java 连接到 Azure 上的 Postgres 数据库 - Can not connect to Postgres database on Azure with Java 我无法连接到 Heroku Postgres 数据库 - I am unable to connect to the Heroku Postgres database 如何将计算机中的MySql数据库连接到android应用程序? - how can i connect the MySql database in my computer to android application.? 如何从 Cloud Run Java 应用程序连接到 Cloud SQL 数据库? - How can I connect from Cloud Run Java application to a Cloud SQL database? 如何在没有受支持的JDBC驱动程序的情况下从Java应用程序连接到SUPRA数据库 - How can I connect to SUPRA database from a Java application, without the supported JDBC driver
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM