I'm facing a strange issue with Salat and this happens especially when I run my Play web application.
Here is the stacktrace:
Caused by: java.util.concurrent.ExecutionException: Boxed Error
at scala.concurrent.impl.Promise$.resolver(Promise.scala:52) ~[scala-library.jar:na]
at scala.concurrent.impl.Promise$.scala$concurrent$impl$Promise$$resolveTry(Promise.scala:44) ~[scala-library.jar:na]
at scala.concurrent.impl.Promise$DefaultPromise.tryComplete(Promise.scala:116) [scala-library.jar:na]
... 9 common frames omitted
Caused by: com.novus.salat.util.GraterGlitch:
GRATER GLITCH - unable to find or instantiate a grater using supplied path name
REASON: Very strange! Path='domain.content.Exam' from pickled ScalaSig causes ClassNotFoundException
Context: 'global'
Path from pickled Scala sig: 'domain.content.Exam'
at com.novus.salat.Context$class.lookup(Context.scala:213) ~[salat-core_2.10-1.9.2.jar:1.9.2]
at com.novus.salat.global.package$$anon$1.lookup(global.scala:29) ~[salat-core_2.10-1.9.2.jar:1.9.2]
at com.novus.salat.package$.grater(package.scala:62) ~[salat-core_2.10-1.9.2.jar:1.9.2]
at com.novus.salat.dao.SalatDAO.<init>(SalatDAO.scala:48) ~[salat-core_2.10-1.9.2.jar:1.9.2]
at domain.content.ExamDAO$.<init>(Exam.scala:31) ~[classes/:na]
at domain.content.ExamDAO$.<clinit>(Exam.scala) ~[classes/:na]
at domain.content.Exam$.getAllExamsForTechnology(Exam.scala:22) ~[classes/:na]
at core.ContentService.allExamsForTechnology(ContentService.scala:30) ~[classes/:na]
at controllers.content.ExamController$$anonfun$allExamsForTechnology$1.apply(ExamController.scala:24) ~[classes/:na]
at controllers.content.ExamController$$anonfun$allExamsForTechnology$1.apply(ExamController.scala:22) ~[classes/:na]
at play.api.mvc.ActionBuilder$$anonfun$apply$10.apply(Action.scala:221) ~[play_2.10.jar:2.2.1]
at play.api.mvc.ActionBuilder$$anonfun$apply$10.apply(Action.scala:220) ~[play_2.10.jar:2.2.1]
at play.api.mvc.Action$.invokeBlock(Action.scala:357) ~[play_2.10.jar:2.2.1]
at play.api.mvc.ActionBuilder$$anon$1.apply(Action.scala:309) ~[play_2.10.jar:2.2.1]
at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$4$$anonfun$apply$5.apply(Action.scala:109) ~[play_2.10.jar:2.2.1]
at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$4$$anonfun$apply$5.apply(Action.scala:109) ~[play_2.10.jar:2.2.1]
at play.utils.Threads$.withContextClassLoader(Threads.scala:18) ~[play_2.10.jar:2.2.1]
at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$4.apply(Action.scala:108) ~[play_2.10.jar:2.2.1]
at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$4.apply(Action.scala:107) ~[play_2.10.jar:2.2.1]
at scala.Option.map(Option.scala:145) ~[scala-library.jar:na]
at play.api.mvc.Action$$anonfun$apply$1.apply(Action.scala:107) ~[play_2.10.jar:2.2.1]
at play.api.mvc.Action$$anonfun$apply$1.apply(Action.scala:100) ~[play_2.10.jar:2.2.1]
at play.api.libs.iteratee.Iteratee$$anonfun$mapM$1.apply(Iteratee.scala:481) ~[play-iteratees_2.10.jar:2.2.1]
at play.api.libs.iteratee.Iteratee$$anonfun$mapM$1.apply(Iteratee.scala:481) ~[play-iteratees_2.10.jar:2.2.1]
at play.api.libs.iteratee.Iteratee$$anonfun$flatMapM$1.apply(Iteratee.scala:517) ~[play-iteratees_2.10.jar:2.2.1]
at play.api.libs.iteratee.Iteratee$$anonfun$flatMapM$1.apply(Iteratee.scala:517) ~[play-iteratees_2.10.jar:2.2.1]
at play.api.libs.iteratee.Iteratee$$anonfun$flatMap$1$$anonfun$apply$13.apply(Iteratee.scala:493) ~[play-iteratees_2.10.jar:2.2.1]
at play.api.libs.iteratee.Iteratee$$anonfun$flatMap$1$$anonfun$apply$13.apply(Iteratee.scala:493) ~[play-iteratees_2.10.jar:2.2.1]
at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24) [scala-library.jar:na]
at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24) [scala-library.jar:na]
... 6 common frames omitted
What is the reason for this strange error?
I ran into the same issue with Play 2.4.x. But sparkr's solution wasn't enough, because Play keeps creating new classloaders on each code change. The following hack (in Globals.scala
) seems to fix the issue:
import play.api.{Play, Application, GlobalSettings}
import com.novus.salat.global.{ctx => SalatGlobalContext}
object Global extends GlobalSettings {
override def onStart(app: Application) = {
SalatGlobalContext.clearAllGraters()
SalatGlobalContext.registerClassLoader(Play.classloader(Play.current))
}
}