문제

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))
  }
}

다른 팁

I added a custom package object that looks like below:

import com.novus.salat.Context
import play.api.Play

package object CustomPlaySalatContext {
  implicit val ctx = new Context {
    val name = "Custom_Classloader"
  }
  ctx.registerClassLoader(Play.classloader(Play.current))
}

Import the above package in the DAO object and the issue is now gone!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top