Where does one place a scala file in the Play Framework 2.0 so that it is compiled as part of the default package? - scala

I am new to Play and Scala, and I am reading Play for Scala from Manning press. I would like to use the instructions to use Squeryl instead of Anorm.
The book mentions that I need to initialize Squeryl in a class that extends GlobalSettings.
import org.squeryl.adapters.H2Adapter
import org.squeryl.{Session, SessionFactory}
import play.api.db.DB import play.api.{Application, GlobalSettings}
object Global extends GlobalSettings {
SessionFactory.concreteFactory = Some(() =>
Session.create(DB.getConnection()(app), new H2Adapter) )
...
As this is an early edition (MEAP) it is not clear about where to place this code...
So I after a little digging on the play site I found the following example that extends GlobalSettings
import play.api._
object Global extends GlobalSettings {
override def onStart(app: Application) {
Logger.info("Application has started")
}
override def onStop(app: Application) {
Logger.info("Application shutdown...")
}
}
The play example gives a little more help but I am still unable to follow the directions, which state : This object must be defined in the default (empty) package.
Which leads to my question: Where does one place a scala file in the Play Framework 2.0 so that it is complied as part of the default package?
Thanks for any help...

GlobalSettings object typically resides in app/Global.scala. Look at zentasks sample.

This does not answer your specific asked question
But, if your question is about "how to use squeryl with Play2 ?", there are some resources you can have a look at :
How to make Squeryl work with the Play! Framework?
https://groups.google.com/d/topic/squeryl/d7hBDNUjE2Y/discussion
And an example : https://github.com/jamesward/play2bars/tree/scala-squeryl

Related

Migrating Play Framework 2.5 - moving from Global.onStart to Dependency Injection

So I am trying to migrate a PlayFramework application from version 2.4.3 to 2.5.6. I am using Squeryl and akka-quartz-scheduler, and Squeryl requires setting up a session manually and akka-quartz-scheduler runs as its own entity, as none of the other modules really depend on it, though it will depend on others. So previously there has been a Global-object to handle them on start up:
import org.squeryl.{Session, SessionFactory}
object Global extends GlobalSettings {
private lazy val injector = Guice.createInjector(CustomModule)
override def onStart(app: Application) {
SessionFactory.concreteFactory = // Squeryl initialization http://squeryl.org/sessions-and-tx.html
injector.getInstance(classOf[CustomScheduler]).initialize()
}
}
This has worked before. However, on 2.5.6 I'm trying to shift away from Global.scala altogether. I'm not sure if this is the best way to do this, but from documentation it seems like it. So I'm trying to create Singleton classes, and load them eagerly before the application loads like instructed here as a replacement for onStart. So like instructed on eager bindings -page I have:
import com.google.inject._
class CustomModule extends AbstractModule {
override def configure() = { // or without override
println("configure called")
bind(classOf[SquerylInitialization]).to(classOf[SquerylInitialization]).asEagerSingleton()
bind(classOf[CustomScheduler]).to(classOf[CustomScheduler]).asEagerSingleton()
}
}
import play.api.{Configuration, Application}
import play.api.db.{DB, DBApi}
import org.squeryl.{SessionFactory, Session}
#Singleton
class SquerylInitialization #Inject()(conf: Configuration, dbApi: DBApi) extends Logging {
SessionFactory.concreteFactory = // Squeryl initialization http://squeryl.org/sessions-and-tx.html
}
import akka.actor.{ActorSystem, ActorRef}
#Singleton
class CustomScheduler #Inject()(system: ActorSystem) extends Logging {
val scheduler: QuartzSchedulerExtension = QuartzSchedulerExtension(system)
// other initialize code here
}
The CustomModule inheriting the AbstractModule and its configure()-method is never called. It is said in Guice documentation that "Alternatively, play will scan the classpath for classes that implement AbstractModule". Documentation might not be the most recent, but that seems to be the way it works.
If for instance on all classes using Squeryl I use dependency injection to load SquerylInitialization it works, but I'm not sure if that's good way to do it as it would have to be required by tons of Classes, and there is hardly any Class depending on the CustomScheduler.
So basically the questions are:
Why isn't the CustomModule calling the configure()-method and eager
loading the Classes, and how that should be fixed?
Is this the standard way to load this kind of functionality, or should some other way used?
So basically comments are correct and the documentation was just out of date, so including
play.modules.enabled += "module.CustomModule"
helped. Thought I tried that as well, but turns out I didn't. Answer just a comment so can't accept that.

How to activate circular dependencies in Play 2.5?

This question originates from a question that I asked two days ago. I implemented my own error handler which extends DefaultHttpErrorHandler. DefaultHttpErrorHandler extends HttpErrorHandler which is also used as a parameter errorHandler: HttpErrorHandler in the WebJarAssets class. First I thought I had a flaw in my design, but James Ward commented that it seems like that I am doing things right.
Long story short, I need to know how I can activate circular dependencies. Unfortunately, there is no example code listed in the Play documentation, so I have no idea where I should set disableCircularProxies(false).
You need a custom GuiceApplicationLoader like:
import play.api.ApplicationLoader
import play.api.inject.guice.{GuiceApplicationLoader, GuiceApplicationBuilder}
class CustomApplicationLoader extends GuiceApplicationLoader {
override protected def builder(context: ApplicationLoader.Context): GuiceApplicationBuilder = {
super.builder(context).disableCircularProxies(false)
}
}
And tell Play to use it in application.conf:
play.application.loader = "CustomApplicationLoader"
Full code example:
https://github.com/webjars/webjars-play/tree/cicular-deps

How to add 'init' and 'destroy' like methods in scala play webapp?

I am very new to Play, I am writing a webapp using scala, in which I wish to implement the following functionality (Play version - 2.3.9):
When the application runs for the first time, five separate variables are to be read from a file (or a DB - this is yet to be decided).
These variables can be globally interfered with and updated while the app runs.
When the app shuts down, the file (or DB) is to be saved with the latest values for these variables.
I need to define sort of java servlet-like init and destroy functionalities to achieve this task. Could somebody guide me on how to achieve this?
Based on play 2.3.9 documentation you should define your hooks via the GlobalSettings:
import play.api._
object Global extends GlobalSettings {
override def onStart(app: Application) {
Logger.info("Application has started")
}
override def onStop(app: Application) {
Logger.info("Application shutdown...")
}
}
But I recommend to move to a newer version >= 2.4, there the GlobalSetting was deprecated, and so the way to add start and end hooks was changed.
In order to define a "start hook" you can add your own Guice module to the application configuration, there you can write what ever you need to heppen when the application starts.
And in order to add a "stop hook" you should use ApplicationLifecycle, see here more.
import scala.concurrent.Future
import javax.inject._
import play.api.inject.ApplicationLifecycle
#Singleton
class MessageQueueConnection #Inject() (lifecycle: ApplicationLifecycle) {
val connection = connectToMessageQueue()
lifecycle.addStopHook { () =>
Future.successful(connection.stop())
}
//...
}

Play 2.4: Schedule a recurring task at app startup with dependency injection

I need to schedule a recurring task on the application start, the task itself is very simple just send to the application a fire-and-forget HTTP call. I'm not a play expert, buy i would assume that s straightforward solution would be something like using play.api.libs.concurrent.Akka.system.schedule in Global.onStart. Since Play 2.4, Global configuration is somewhat deprecated in favor of new Guice DI. Hacking the advice from the DI documentation i couldn't come up with a nice solution for this issue. The best i managed to get is writing a wrapper on top of GuiceApplicationLoader calling a custom implementation of BuiltInComponentsFromContext, but in this case i can't use injection to get WSClient. What's the best way to rewrite something like this with Play 2.4:
object Global extends GlobalSettings {
override def onStart(app: Application) = {
Akka.system.schedule(2.hours, 2.hours, theTask)
}
}
Update: this is now better documented for Play 2.6: https://www.playframework.com/documentation/2.6.x/ScheduledTasks
You can solve this by creating a module like this (attention to code comments):
package tasks
import javax.inject.{Singleton, Inject}
import akka.actor.ActorSystem
import com.google.inject.AbstractModule
import play.api.inject.ApplicationLifecycle
// Using the default ExecutionContext, but you can configure
// your own as described here:
// https://www.playframework.com/documentation/2.4.x/ThreadPools
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import scala.concurrent.Future
import scala.concurrent.duration._
class MyRecurrentTaskModule extends AbstractModule {
override def configure() = {
// binding the RecurrentTask as a eager singleton will force
// its initialization even if RecurrentTask is not injected in
// any other object. In other words, it will starts with when
// your application starts.
bind(classOf[RecurrentTask]).asEagerSingleton()
}
}
#Singleton
class RecurrentTask #Inject() (actorSystem: ActorSystem, lifecycle: ApplicationLifecycle) {
// Just scheduling your task using the injected ActorSystem
actorSystem.scheduler.schedule(1.second, 1.second) {
println("I'm running...")
}
// This is necessary to avoid thread leaks, specially if you are
// using a custom ExecutionContext
lifecycle.addStopHook{ () =>
Future.successful(actorSystem.shutdown())
}
}
After that, you must enable this module adding the following line in your conf/application.conf file:
play.modules.enabled += "tasks.MyRecurrentTaskModule"
Then, just start you application, fire a request to it and see the scheduled task will run every each second.
References:
Understanding Play thread pools
Play Runtime Dependency Injection for Scala
Integrating with Akka
Related questions:
How to correctly schedule task in Play Framework 2.4.2 scala?
Was asynchronous jobs removed from the Play framework? What is a better alternative?

Play Framework: Inject multiple dependencies using constructor injection in the controller

What is the right way to inject multiple dependencies using constructor injection for a controller in Play Framework (2.4.x, which provides guice based DI out of the box) in Scala?
For example,
class ExampleController #Inject() (serviceOne: ServiceOne, serviceTwo: ServiceTwo) extends Controller {
}
The above won't compile saying only one or no constructor arg can be injected.
Was not able to find any good references regarding as how to get this working. Any help is appreciated. Thanks.
You may need to prepend val to the parameters:
class ExampleController #Inject() (val serviceOne: ServiceOne, val serviceTwo: ServiceTwo) extends Controller {
And also check that you have the correct import:
import javax.inject.Inject
Here you also can find an example with multiple dependencies, maybe it helps.
Your code is correct. Additionally to that, you need to configure a module in your application.conf
play.modules.enabled += "com.example.HelloModule"
And then in this very Module you need to describe your dependency injected classes:
import play.api.inject._
class HelloModule extends Module {
def bindings(environment: Environment,
configuration: Configuration) = Seq(
bind[Hello].qualifiedWith("en").to[EnglishHello],
bind[Hello].qualifiedWith("de").to[GermanHello]
)
}
For the offical documentation see this link.