playframework / play-slick

Slick Plugin for Play
Apache License 2.0
803 stars 283 forks source link

Issue with Play 2.1.5 #104

Closed suriyanto closed 11 years ago

suriyanto commented 11 years ago

I tried using Play Slick 0.4.0 with Play 2.1.5, but have been encountering issue. First 0.4.0 is bound to Play 2.1.2 and I managed to get around that dependency by using intransitive() in the sbt file, but afterwards it throws a big fat Unrecoverable Error during compilation.

exception when typing play.api.db.slick.package/class scala.reflect.internal.Trees$Select bad symbolic reference. A signature in package.class refers to term mvc in package play.api which is not available. It may be completely missing from the current classpath, or the version on the classpath might be incompatible with the version used when compiling package.class. in file /Users/sbongso/Documents/dev/MiuInsights/trunk/server/insights-deal-persistence/src/main/scala/com/rms/miu/insights/deal/persistence/ProgramsComponent.scala scala.reflect.internal.Types$TypeError: bad symbolic reference. A signature in package.class refers to term mvc in package play.api which is not available. It may be completely missing from the current classpath, or the version on the classpath might be incompatible with the version used when compiling package.class. at scala.reflect.internal.pickling.UnPickler$Scan.toTypeError(UnPickler.scala:847) at scala.reflect.internal.pickling.UnPickler$Scan$LazyTypeRef.complete(UnPickler.scala:854) ....

Is there a version of Play Slick that works with Play 2.1.5?

Suriyanto

freekh commented 11 years ago

Oh god, how i loathe ivy. I think I need your build.scala file to figure out what is going on here. Is that possible?

Suriyanto Lee notifications@github.com wrote:

I tried using Play Slick 0.4.0 with Play 2.1.5, but have been encountering issue. First 0.4.0 is bound to Play 2.1.2 and I managed to get around that dependency by using intransitive() in the sbt file, but afterwards it throws a big fat Unrecoverable Error during compilation.

exception when typing play.api.db.slick.package/class scala.reflect.internal.Trees$Select bad symbolic reference. A signature in package.class refers to term mvc in package play.api which is not available. It may be completely missing from the current classpath, or the version on the classpath might be incompatible with the version used when compiling package.class. in file /Users/sbongso/Documents/dev/MiuInsights/trunk/server/insights-deal-persistence/src/main/scala/com/rms/miu/insights/deal/persistence/ProgramsComponent.scala scala.reflect.internal.Types$TypeError: bad symbolic reference. A signature in package.class refers to term mvc in package play.api which is not available. It may be completely missing from the current classpath, or the version on the classpath might be incompatible with the version used when compiling package.class. at scala.reflect.internal.pickling.UnPickler$Scan.toTypeError(UnPickler.scala:847) at scala.reflect.internal.pickling.UnPickler$Scan$LazyTypeRef.complete(UnPickler.scala:854) ....

Is there a version of Play Slick that works with Play 2.1.5?

Suriyanto


Reply to this email directly or view it on GitHub: https://github.com/freekh/play-slick/issues/104

Sent from my Android device with K-9 Mail. Please excuse my brevity.

suriyanto commented 11 years ago

Thanks very much for responding so quickly, Fredrik.

Below is my Build.scala:

import sbt. import sbt.Keys.

object PersistenceBuild extends Build { val main = Project(id = "persistence", base = file(".")) }

And the dependency in build.sbt:

scalaVersion := "2.10.2"

libraryDependencies ++= Seq( "mysql" % "mysql-connector-java" % "5.1.26", "com.h2database" % "h2" % "1.3.173", "com.typesafe.slick" %% "slick" % "1.0.1", "org.slf4j" % "slf4j-nop" % "1.6.4", "org.scalatest" % "scalatest_2.10" % "1.9.2", "com.typesafe.play" %% "play-slick" % "0.4.0" intransitive() )

Whenever I added the following import in a scala class, the compile error is triggered:

import play.api.db.slick.Config.driver.simple._

Please let me know if you need anything else.

Thanks again, Suriyanto

freekh commented 11 years ago

Sure :) I AM not sure if I can look further into today but perhaps tomorrow or Monday next week. Should be enough to reproduce though

Suriyanto Lee notifications@github.com wrote:

Thanks very much for responding so quickly, Fredrik.

Below is my Build.scala:

import sbt. import sbt.Keys.

object PersistenceBuild extends Build { val main = Project(id = "persistence", base = file(".")) }

And the dependency in build.sbt:

scalaVersion := "2.10.2"

libraryDependencies ++= Seq( "mysql" % "mysql-connector-java" % "5.1.26", "com.h2database" % "h2" % "1.3.173", "com.typesafe.slick" %% "slick" % "1.0.1", "org.slf4j" % "slf4j-nop" % "1.6.4", "org.scalatest" % "scalatest_2.10" % "1.9.2", "com.typesafe.play" %% "play-slick" % "0.4.0" intransitive() )

Whenever I added the following import in a scala class, the compile error is triggered:

import play.api.db.slick.Config.driver.simple._

Please let me know if you need anything else.

Thanks again, Suriyanto


Reply to this email directly or view it on GitHub: https://github.com/freekh/play-slick/issues/104#issuecomment-26619478

Sent from my Android device with K-9 Mail. Please excuse my brevity.

freekh commented 11 years ago

I couldn't reproduce your exact error. However, it looks like there are multiple issues in the build.sbt and the Build.scala file, if you want to use this with Play. So that it has been said, this is completely unrelated to play-slick.

1) to create a Play project you need the Play project settings so Project in the Build.scala must be play.Project 2) you cannot do intransitive() on play-slick without adding the right version of all of the different libraries. the standard play libraries will automagically be updated to 2.1.5, but any (play) dependency you have that is not on the classpath will not be updated.

For me this works perfectly:

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

object PersistenceBuild extends Build {

  val main = play.Project("persistence", "1.0-SNAPSHOT")
}

and build.sbt:

scalaVersion := "2.10.2"

libraryDependencies ++= Seq(
  play.Project.javaCore force(), //force is not really required, but you never know what Ivy can decide to do...
  play.Project.jdbc force(),
  "mysql" % "mysql-connector-java" % "5.1.26",
  "com.h2database" % "h2" % "1.3.173",
  "com.typesafe.slick" %% "slick" % "1.0.1",
  "org.slf4j" % "slf4j-nop" % "1.6.4",
  "org.scalatest" % "scalatest_2.10" % "1.9.2",
  "com.typesafe.play" %% "play-slick" % "0.4.0"
)

@suriyanto tell me if this fixes the classpath issues so I can close this issue.

suriyanto commented 11 years ago

Thanks for looking at this over the weekend.

I modified the build file per your instruction and the compile error went away. It's great. Issue closed.

However this project is not play project. It is actually my repository layer that provides hook to database and will be utilized by a play project. I am not sure what the side effect is to make this as play project instead of a regular sbt project.

freekh commented 11 years ago

My pleasure! I have a cold, and what better way to get better than to relax and eliminate some issues :)

I didn't realise the obvious conclusion that it must be a repository layer.

There shouldn't be any issues in doing that provided that you have all the dependencies that play-slick requires on your classpath. Again, Ivy is a bit tricky to trick into using the exact right version. Theoretically there shouldn't be any reason why you can't leave the dependencies from Play like they are: if you build your repo layer with play-slick's play version (2.1.2) and then deploy onto a web app that uses 2.1.5, the versions should be automatically overridden (you have to make sure all of them are in fact overridden though) and you should be using 2.1.5. If the deployed solution do not use the right version or if you need to build your repo layer with a specific version of play, you must tell sbt that you want to override them (by using force()) . Remember to add javaCore and jdbc when you do this, because play-slick 0.4.0 depends on them (javaCore is not a dependency anymore in play-slick 0.5.0.8) and it is probably a good idea to use the same version of the different play modules everywhere.In Ivy it is possible to overwrite, but it is not possible with sbt as far as I can tell.

That being said, and I think this is important, your repo layer might not really need play-slick - in my head it seems much more logical to use just slick for your repo layer, then use play-slick during the integration in the play app. If your repo layer needs play-slick, perhaps you should give it's design another thought?

suriyanto commented 11 years ago

Completely agreed with your observation on the repository layer dependency.

There are 3 features that I was hoping to get out from play-slick. One is to be able to use the play config file, second not to need to depend on a database specific slick driver, ie. H2Driver, MySQLDriver, and third to be able to tap into the play evolution. I saw that all of these are provided by play-slick and I was hoping to get a free ride.

Would you have recommendations along these lines?

Thanks so much for giving me this level headed suggestion.

freekh commented 11 years ago

Sure thing :) Again, I do not know your code, so it is possible that if you really want these features it makes sense to use play-slick.

I guess again it depends on what you need the play config file for and why you want the play evolutions in the data layer. If the config file is to figure out which type of DB your using, perhaps using the cake pattern as done here might help you out (this solves the Driver requirement as well): https://github.com/freekh/slick-examples/blob/cake-pattern-example/src/main/scala/scala/slick/examples/lifted/MultiDBCakeExample.scala

If you want the evolutions I am afraid play-slick is required. Perhaps you could tell my as to why exactly you need them in your DB layer (exactly the use case). I could guess of course, but it would be simpler if you could just tell me :)

suriyanto commented 11 years ago

My requirement on the DB layer is actually quite simple. I would like the DB layer to have little dependencies, so being able to work directly with Slick is really a plus.

I explored the MultiDBCakeExample before, but due to the structure of the traits and objects, I was having difficulties trying to set up foreign key relationship between the tables definition. I tried again yesterday to make sure that I didn't miss anything, but it confirms the same issue.

Not sure if you have seen that example, but if I add the following foreign key definition in Users object, then it becomes as issue as the Pictures object is inside PictureComponent trait so it is not accessible from outside.

def pictureKey = foreignKey("FK_USERPICTURE", pictureId, PictureComponent.Pictures)(.id.get)

I posted this on the Slick Example git project, but would really appreciate if you have suggestion.

diwa-zz commented 11 years ago

Did you try

def pictureKey = foreignKey("FK_USER_PICTURE", pictureId, Pictures)(_.id.get)

Since UserComponent is declaring a self trait to include PictureComponent, this should ideally work.

freekh commented 11 years ago

@diwa yep, I agree with that one.

@suriyanto an example of what @diwa mentions is here: https://github.com/freekh/play-slick/blob/master/samples/computer-database/app/models/Models.scala

AFAICS, the exact same issue is treated there.

If this solves it, but now you cannot figure out how to handle the profiles, tell me and I can try to create an example.