Play-ReactiveMongo — можно ли использовать плагин вне контроллера?

Я получаю сообщение об ошибке, если пытаюсь использовать play-reactive mongo в сервисе SecureSocial в памяти.

import play.api.Play.current

/**
 * A Sample In Memory user service in Scala
 *
 * IMPORTANT: This is just a sample and not suitable for a production environment since
 * it stores everything in memory.
 */
class InMemoryUserService(application: Application) extends UserServicePlugin(application) {

  private var users = Map[String, Identity]()
  private var tokens = Map[String, Token]()
[...]

Но, похоже, внутри контроллера все работает нормально:

import play.api.Play.current

object Application extends Controller with securesocial.core.SecureSocial {


  val db = ReactiveMongoPlugin.db
  lazy val collections = db("persons")
[...]

Можно ли использовать контекст воспроизведения вне контроллера?

Ошибка, которую я получаю, - это попытка доступа к ресурсу, который использует указанную ошибку броска класса:

! @6dl5aj9h3 - Internal server error, for (GET) [/login] ->

play.api.PlayException: Cannot load plugin[An exception occurred during Plugin [service.InMemoryUserService] initialization]
    at play.api.WithDefaultPlugins$$anonfun$plugins$1$$anonfun$apply$9.apply(Application.scala:149) ~[play_2.10.jar:2.1.0]
    at play.api.WithDefaultPlugins$$anonfun$plugins$1$$anonfun$apply$9.apply(Application.scala:130) ~[play_2.10.jar:2.1.0]
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) ~[scala-library.jar:na]
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) ~[scala-library.jar:na]
    at scala.collection.immutable.List.foreach(List.scala:309) ~[scala-library.jar:na]
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:244) ~[scala-library.jar:na]
Caused by: play.api.PlayException: Cannot load plugin[An exception occurred during Plugin [service.InMemoryUserService] initialization]
    at play.api.WithDefaultPlugins$$anonfun$plugins$1$$anonfun$apply$9.apply(Application.scala:149) ~[play_2.10.jar:2.1.0]
    at play.api.WithDefaultPlugins$$anonfun$plugins$1$$anonfun$apply$9.apply(Application.scala:130) ~[play_2.10.jar:2.1.0]
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) ~[scala-library.jar:na]
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) ~[scala-library.jar:na]
    at scala.collection.immutable.List.foreach(List.scala:309) ~[scala-library.jar:na]
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:244) ~[scala-library.jar:na]
         [repeats a lot]
Caused by: play.api.PlayException: Cannot load plugin[An exception occurred during Plugin [service.InMemoryUserService] initialization]
    at play.api.WithDefaultPlugins$$anonfun$plugins$1$$anonfun$apply$9.apply(Application.scala:149) ~[play_2.10.jar:2.1.0]
    at play.api.WithDefaultPlugins$$anonfun$plugins$1$$anonfun$apply$9.apply(Application.scala:130) ~[play_2.10.jar:2.1.0]
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) ~[scala-library.jar:na]
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) ~[scala-library.jar:na]
    at scala.collection.immutable.List.foreach(List.scala:309) ~[scala-library.jar:na]
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:244) ~[scala-library.jar:na]
java.lang.StackOverflowError: null
    at java.io.UnixFileSystem.getBooleanAttributes0(Native Method) ~[na:1.6.0_43]
    at java.io.UnixFileSystem.getBooleanAttributes(UnixFileSystem.java:228) ~[na:1.6.0_43]
    at java.io.File.exists(File.java:733) ~[na:1.6.0_43]
    at sun.misc.URLClassPath$FileLoader.getResource(URLClassPath.java:999) ~[na:1.6.0_43]
    at sun.misc.URLClassPath$FileLoader.findResource(URLClassPath.java:966) ~[na:1.6.0_43]
    at sun.misc.URLClassPath$1.next(URLClassPath.java:196) ~[na:1.6.0_43]

person JasonG    schedule 22.03.2013    source источник
comment
это полная трассировка стека?   -  person Jorge    schedule 26.03.2013
comment
Это переполнение стека, так что вы увидите, что я просто пропустил бесконечные циклы с помощью [много повторов]. Это верх и низ трассировки стека до переполнения. Я предполагаю, что вам не нужны все повторяющиеся кадры :)   -  person JasonG    schedule 27.03.2013


Ответы (2)


Да, это возможно. Я создал плагин, который проверяет файлы в папке. Если он найден, он читает файл, а затем сохраняет материал в моем экземпляре монго.

package plugins

import play.api.{Logger, Application, Plugin}
import akka.actor.Cancellable
import play.api.libs.concurrent.Akka
import scala.io.Source
import scalax.file.Path
import org.joda.time.DateTime
import org.joda.time.format.DateTimeFormat
import play.modules.reactivemongo.ReactiveMongoPlugin
import java.io.{IOException, FileNotFoundException}
import models.LeadCategory
import reactivemongo.api.DefaultDB
import scala.concurrent.ExecutionContext
import ExecutionContext.Implicits.global

/**
 * User: jakobdobrzynski
 * Date: 4/24/13
 * Time: 10:34 AM
 */
class WordImporter(application: Application) extends Plugin {

  val defaultInterval = 2
  var cancellable: Option[Cancellable] = None    

  val leadCategoryPathKey = "lead.categories.path"
  val newFile = ".new"
  val doneFiles = ".done"


  override def onStop() {
    cancellable.map(_.cancel())
  }

  override def onStart() {
    import play.api.Play.current
    import scala.concurrent.duration._
    import play.api.libs.concurrent.Execution.Implicits._

    val i = defaultInterval
    val newPath = current.configuration.getString(leadCategoryPathKey + newFile).getOrElse("")
    val donePath = current.configuration.getString(leadCategoryPathKey + doneFiles).getOrElse("")
    val db = ReactiveMongoPlugin.db

    cancellable = if (true) {
      Some(
        Akka.system.scheduler.schedule(0 seconds, i minutes) {
          Logger.info("Looking for files")
          val files = new java.io.File(newPath).listFiles
          for(f <- files) {
            if(f.getName.endsWith(".csv")) {
              handleCsvFile(f.getName, newPath, donePath, db)
            }
          }
          Logger.info("Done looking for files")
        })

    } else None
  }

  /*
  "caregoryId" -> BSONLong(leadCategory.categoryId),
  "categoryName" -> BSONString(leadCategory.categoryName),
  "word" -> BSONString(leadCategory.categoryName),
  "creationDate" -> leadCategory.creationDate.map(date => BSONDateTime(date.getMillis)),
  "updateDate" -> leadCategory.updateDate.map(date => BSONDateTime(date.getMillis)))
  */

  def handleCsvFile(fileName: String, newPath: String, donePath: String, db : DefaultDB) =    {

    Logger.info("Handling csv file: "+fileName)    
    lazy val collection = db("leadCategories")    
    try {
      val file = Source.fromFile(newPath + fileName)
      val iter = file.getLines().map(_.split(","))
      iter foreach (a => {
        collection.insert(LeadCategory(None, a(2).toLong, (""+a(1)).toLowerCase(), (""+a(0)).toLowerCase(), Some(DateTime.now()), Some(DateTime.now())))
      })
      Logger.info("Reading done! Time to move file")
      val path: Path = Path.fromString(newPath+fileName)

      val now = DateTime.now()
      val pattern = DateTimeFormat.forPattern("dd-MM-yyyy-hh-mm-ss")
      val nameParts = fileName.split("\\.")
      val dest: Path = Path.fromString(donePath+nameParts(0)+"-" + pattern.print(now) + "."+nameParts(1))
      path.moveTo(target = dest)
    } catch {
      case e: FileNotFoundException => {
        Logger.error("No file found")
      }
      case e: IOException => {
        Logger.error("Something went wrong when reading the file")
      }
    }
  }
}

Магия для меня заключалась в этих двух строчках:

import scala.concurrent.ExecutionContext
import ExecutionContext.Implicits.global

Надеюсь поможет =)

person jakob    schedule 26.04.2013
comment
Спасибо за ответ. Я попробую. - person JasonG; 26.04.2013
comment
Теперь я гораздо лучше знаком с akka - не работал над этой частью. Я проверю контекст выполнения. - person JasonG; 26.04.2013

У меня была такая же ошибка, когда я пытался реализовать безопасный социальный UserService с ReactiveMongo. В итоге я решил это, изменив

  val db = ReactiveMongoPlugin.db(application)

to

  def db = ReactiveMongoPlugin.db(application)
person yzernik    schedule 21.11.2013