Play-ReactiveMongo - 可以在控制器外使用插件吗?

时间:2013-03-22 04:47:52

标签: mongodb scala playframework-2.0 securesocial

如果我尝试在内存服务的securesocial中使用play-reactive mongo,我会收到错误。

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]

2 个答案:

答案 0 :(得分:2)

是的,这是可能的。我创建了一个插件来检查文件夹中的文件。如果发现它会读取文件,然后将内容保存到我的mongo实例中。

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

希望有帮助=)

答案 1 :(得分:2)

当我尝试使用ReactiveMongo实现securesocial UserService时,我遇到了同样的错误。我最终通过改变

解决了这个问题
  val db = ReactiveMongoPlugin.db(application)

  def db = ReactiveMongoPlugin.db(application)