Play Framework:反向路由时的NoSuchFieldError

时间:2014-05-30 14:49:52

标签: playframework

这是我的common.routes文件:

GET     /emails/:deflated   controllers.common.Emails.viewInBrowser(deflated)

......在这里我的控制器:

package controllers.common

object Emails extends Controller {

  def viewInBrowser(deflated: String) = Action { implicit request =>
    GZip.inflate(deflated) match {
      case Success(inflated) => Ok(Html(inflated))
      case Failure(e) => {
        Logger.warn(s"error inflating email from url", e)
        val support = configuration.getString("application.emails.support")
        BadRequest(views.html.badRequest(Messages("common.error.invalidOrMalformedUrl", support)))
      }
    }
  }
}

上面的代码运行正常...但如果我像这样反转路线

import controllers.common.routes
...

val sslEnabled = configuration.getBoolean("ssl").getOrElse(false)
val emailUrl = routes.Emails.viewInBrowser(true).absoluteURL(sslEnabled)

......我总是出现以下异常:

java.lang.NoSuchFieldError: Emails
at utils.common.RoutesHelper$.emailUrl(RoutesHelper.scala:51)
at services.common.DefaultEmailComponent$DefaultRichBody.apply(EmailComponent.scala:64)
at services.common.DefaultEmailServiceComponent$DefaultEmailService.sendEmail(EmailServiceComponent.scala:81)
at utils.auth.EmailHelper$.sendUserVerificationEmail(EmailHelper.scala:32)
at controllers.auth.Users$$anonfun$create$1$$anonfun$8$$anonfun$apply$60$$anonfun$apply$61.apply(Users.scala:381)
at controllers.auth.Users$$anonfun$create$1$$anonfun$8$$anonfun$apply$60$$anonfun$apply$61.apply(Users.scala:379)
at scala.util.Success$$anonfun$map$1.apply(Try.scala:206)[ERROR] [05/30/2014 16:35:05.350] [play-akka.actor.default-dispatcher-4] [ActorSystem(play)] Uncaught error from thread [play-akka.actor.default-dispatcher-4] shutting down JVM since 'akka.jvm-exit-on-fatal-error' is enabled

有什么想法吗?我验证了我所能做的一切(配置文件,路由,控制器)......但无法弄清问题是什么。我正在使用Play 2.2.3。

更新

有些奇怪的是,我试图将我的Emails控制器移动到另一个包(即models),在这种情况下,反向路由再次工作。 Play中某处有错误吗?

2 个答案:

答案 0 :(得分:5)

据我所知,如果在根项目和其中一个子项目中的同一个包中定义了路由,则生成的子项目routes对象会从根项目和所有代码中隐藏相同的对象引用旧的routes对象会变得错误。

E.g。如果根项目中的routes文件包含路径

GET /path       mypackage.MyController.someAction

并且subproject.routes文件包含路径

GET /otherPath  mypackage.MyOtherController.otherAction

两个项目在构建期间生成mypackage.routes个对象,其中一个在运行时隐藏另一个。

解决方案是在自己的包中定义所有未在根项目中显示的子项目路由。

答案 1 :(得分:1)

在花了一整夜才弄清楚如何完成这项工作后,我刚刚修改了这样的路线

GET     /emails/:deflated   controllers.common.webmail.Emails.viewInBrowser(deflated)

我的控制器是这样的:

package controllers.common.webmail

object Emails extends Controller {
  ...
}

将包重命名为controllers.common.webmail解决了问题,现在反向路由工作......但不要问我原因: - (

我猜Play中应该有一个错误。我希望有所帮助。