Question

I have a project that's been finished for about a month that I made using Play 2.1.1, slick, and MySQL. Now I need to move this over to MSSQL and I'm having some issues.

My application compiles fine, and finds the drivers, but whenever I try to make the connection I get an [RuntimeException: java.lang.ExceptionInInitializerError] on the site, and a more detailed error in my console is:

play.api.Application$$anon$1: Execution exception[[RuntimeException: java.lang.ExceptionInInitializerError]]
    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.lang.RuntimeException: java.lang.ExceptionInInitializerError
    at play.api.mvc.ActionBuilder$$anon$1.apply(Action.scala:222) ~[play_2.10.jar:2.1.1]
    at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$2$$anonfun$apply$5$$anonfun$apply$6.apply(Action.scala:109) ~[play_2.10.jar:2.1.1]
    at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$2$$anonfun$apply$5$$anonfun$apply$6.apply(Action.scala:109) ~[play_2.10.jar:2.1.1]
    at play.utils.Threads$.withContextClassLoader(Threads.scala:18) ~[play_2.10.jar:2.1.1]
    at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$2$$anonfun$apply$5.apply(Action.scala:108) ~[play_2.10.jar:2.1.1]
    at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$2$$anonfun$apply$5.apply(Action.scala:106) ~[play_2.10.jar:2.1.1]Caused by: java.lang.ExceptionInInitializerError: null
    at controllers.Application$$anonfun$addLicense$1.apply(Application.scala:18) ~[na:na]
    at controllers.Application$$anonfun$addLicense$1.apply(Application.scala:17) ~[na:na]
    at play.api.mvc.ActionBuilder$$anon$1.apply(Action.scala:217) ~[play_2.10.jar:2.1.1]
    at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$2$$anonfun$apply$5$$anonfun$apply$6.apply(Action.scala:109) ~[play_2.10.jar:2.1.1]
    at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$2$$anonfun$apply$5$$anonfun$apply$6.apply(Action.scala:109) ~[play_2.10.jar:2.1.1]
    at play.utils.Threads$.withContextClassLoader(Threads.scala:18) ~[play_2.10.jar:2.1.1]
Caused by: play.api.Configuration$$anon$1: Configuration error[Slick error : Unknown jdbc driver found in application.conf: [net.sourceforge.jtds.jdbc.Driver]]
    at play.api.Configuration$.play$api$Configuration$$configError(Configuration.scala:80) ~[play_2.10.jar:2.1.1]
    at play.api.Configuration.reportError(Configuration.scala:558) ~[play_2.10.jar:2.1.1]
    at play.api.db.slick.Config$.driver(Config.scala:21) ~[play-slick_2.10-0.3.3.jar:0.3.3]
    at play.api.db.slick.Config$.driver$lzycompute(Config.scala:7) ~[play-slick_2.10-0.3.3.jar:0.3.3]
    at play.api.db.slick.Config$.driver(Config.scala:7) ~[play-slick_2.10-0.3.3.jar:0.3.3]
    at models.License$.<init>(License.scala:38) ~[na:na]

The most interesting thing that I've found is this line though:

Caused by: play.api.Configuration$$anon$1: Configuration error[Slick error : Unknown jdbc driver found in application.conf: [net.sourceforge.jtds.jdbc.Driver]]

It found the driver because if I put in the wrong name it gives me an error;with this entered it does not. I have the jtds driver in my lib directory.

I also do connect to the db on startup

[info] play - database [default] connected at jdbc:jtds:sqlserver://ServerAddress/EGLC

Some additional info:

application.conf:

db.default.url="jdbc:jtds:sqlserver://ServerAddress/EGLC"
db.default.driver=net.sourceforge.jtds.jdbc.Driver
db.default.user="sa"
db.default.password="pass"
slick.default="models.*"

Build.scala:

val appDependencies = Seq(
// Add your project dependencies here,
jdbc,
"mysql" % "mysql-connector-java" % "5.1.25",
"net.sourceforge.jtds" % "jtds" % "1.3.1",
"com.typesafe.play" %% "play-slick" % "0.3.3"
)

EDIT When I refresh a page though I get a different exception with a new set of errors that don't even mention jtds

play.api.Application$$anon$1: Execution exception[[RuntimeException: java.lang.NoClassDefFoundError: Could not initialize class models.Location$]]
    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.lang.RuntimeException: java.lang.NoClassDefFoundError: Could not initialize class models.Location$
    at play.api.mvc.ActionBuilder$$anon$1.apply(Action.scala:222) ~[play_2.10.jar:2.1.1]
    at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$2$$anonfun$apply$5$$anonfun$apply$6.apply(Action.scala:109) ~[play_2.10.jar:2.1.1]
    at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$2$$anonfun$apply$5$$anonfun$apply$6.apply(Action.scala:109) ~[play_2.10.jar:2.1.1]
    at play.utils.Threads$.withContextClassLoader(Threads.scala:18) ~[play_2.10.jar:2.1.1]
    at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$2$$anonfun$apply$5.apply(Action.scala:108) ~[play_2.10.jar:2.1.1]
    at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$2$$anonfun$apply$5.apply(Action.scala:106) ~[play_2.10.jar:2.1.1]
Caused by: java.lang.NoClassDefFoundError: Could not initialize class models.Location$
    at controllers.Application$$anonfun$locations$1$$anonfun$apply$12$$anonfun$apply$13.apply(Application.scala:47) ~[na:na]
    at controllers.Application$$anonfun$locations$1$$anonfun$apply$12$$anonfun$apply$13.apply(Application.scala:46) ~[na:na]
    at controllers.Secured$$anonfun$IsAuthenticated$3$$anonfun$apply$3.apply(Auth.scala:38) ~[na:na]
    at controllers.Secured$$anonfun$IsAuthenticated$3$$anonfun$apply$3.apply(Auth.scala:38) ~[na:na]
    at play.api.mvc.ActionBuilder$$anon$1.apply(Action.scala:217) ~[play_2.10.jar:2.1.1]
    at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$2$$anonfun$apply$5$$anonfun$apply$6.apply(Action.scala:109) ~[play_2.10.jar:2.1.1]
Was it helpful?

Solution

play-slick doesn't know the jTDS driver. While Slick in general supports SQL server, play-slick makes a connection from driver class name to Slick driver:

private def driverByName : String => Option[ExtendedDriver] = Map(
   "org.apache.derby.jdbc.EmbeddedDriver" -> DerbyDriver
   ,"org.h2.Driver" -> H2Driver
   ,"org.hsqldb.jdbcDriver" -> HsqldbDriver
   ,"com.mysql.jdbc.Driver" -> MySQLDriver
   ,"org.postgresql.Driver" -> PostgresDriver
   ,"org.sqlite.JDBC" -> SQLiteDriver
   ,"com.microsoft.sqlserver.jdbc.SQLServerDriver" -> SQLServerDriver
).get(_)

As you can see, Microsoft's driver is supported while jTDS is not. You can now either use Microsoft's JDBC driver or modify play-slick. The change is simple. Just add the line

,"net.sourceforge.jtds.jdbc.Driver" -> SQLServerDriver

and it should work.

I have seen the issue that you have raised on the project's GitHub page. I have sent a pull request that should resolve this issue. Maybe it gets incorporated into play-slick's next version.

OTHER TIPS

I know this is an old post, but just trying to help whoever lands here. With Slick 3.2.3 using Microsoft SQL Server is really easy. For your SBT project following configurations needs to go to the application.conf file

sqlserver = {
 driver = "slick.jdbc.SQLServerProfile$"
 db {
  host = ${?SQLSERVER_HOST}
  port = ${?SQLSERVER_PORT}
  databaseName = ${?SQLSERVER_DB_NAME}

  url = "jdbc:sqlserver://"${sqlserver.db.host}":"${sqlserver.db.port}";databaseName="${sqlserver.db.databaseName}
  user = ${?SQLSERVER_USERNAME}
  password = ${?SQLSERVER_PASSWORD}
 }
}

and the following code snippet can be used to get the database instance

val dbConfig: DatabaseConfig[JdbcProfile] = DatabaseConfig.forConfig("sqlserver")
val db: JdbcProfile#Backend#Database = dbConfig.db

And in order to enable the MS SQL API for your FRM, the following import can be used

 import slick.jdbc.SQLServerProfile.api._

I think it'll be easy to understand the setup using a working example, which is available here: Using Microsoft SQL Server with Scala Slick

I should add jtds driver as a dependency in your project:

val appDependencies = Seq(
// Add your project dependencies here,
jdbc,
"com.typesafe.play" %% "play-slick" % "0.3.3",
"net.sourceforge.jtds" % "jtds" % "1.3.0"
)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top