Reputation: 9724
Here is my common.routes
file:
GET /emails/:deflated controllers.common.Emails.viewInBrowser(deflated)
... and here my controller:
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)))
}
}
}
}
The code above works fine... but if I reverse route like this
import controllers.common.routes
...
val sslEnabled = configuration.getBoolean("ssl").getOrElse(false)
val emailUrl = routes.Emails.viewInBrowser(true).absoluteURL(sslEnabled)
... I always the the following exception:
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
Any idea? I verified everything I could (configuration files, routes, controllers)... but no way to figure out what the problem is. I'm using Play 2.2.3.
UPDATE
What's very strange is that I've tried to move my Emails
controller into another package (i.e. models
) and in that case reverse routing works again. Is there a bug somewhere in Play?
Upvotes: 2
Views: 736
Reputation: 1094
As I understand, if there are routes defined in the same package in the root project and in one of the sub-projects the generated sub-project routes
object hides the same object from root project and all the code referencing the old routes
object becomes erroneous.
E.g. if the routes
file in the root project contains a route
GET /path mypackage.MyController.someAction
and the subproject.routes
file contains a route
GET /otherPath mypackage.MyOtherController.otherAction
both projects generate the mypackage.routes
objects during build and one of them hides the another one in the runtime.
The solution is to define all the sub-project routes in its own packages that are not presented in the root project.
Upvotes: 5
Reputation: 9724
After having spent the whole night to figure out how to make this work, I've just modified the routes like this
GET /emails/:deflated controllers.common.webmail.Emails.viewInBrowser(deflated)
and my controller like this:
package controllers.common.webmail
object Emails extends Controller {
...
}
Renaming the package to controllers.common.webmail
solves the problem and reverse routing works now... but don't ask me why :-(
I guess there should be a bug in Play. I hope that helps.
Upvotes: 1