How can I log in Play Framework using Scala? - scala

I have updated Play Framework up to 2.7 and I got following warning:
method info in object Logger is deprecated (since 2.7.0): Create an instance of via Logger(...) and use the same-named method. Or use SLF4J directly.
So my questions are:
Should I create an instance of Logger and pass it to each component
when I want to use it?
P.S.:
In project not based on Play Framework, I used to use scala-logging that is a wrapper for SLF4J. Can this be a solution?

Play 2.7 provides a trait for Scala similar to scala-logging. It creates a val which you can use it in you class/object:
import play.api.Logging
class MyClass extends Logging {
// `logger` is automaticaly defined by the `Logging` trait:
logger.info("hello!")
}
So there is another way to log in Play now.

Related

In Play framework, how would I replace executing a method in Global settings?

I'm using Play framework for a Scala application and will need to migrate to 2.6.x from 2.5.x
The Global settings class will be removed and I currently rely on it to set the joda DateTimeZone default like so: DateTimeZone.setDefault(DateTimeZone.forID("Europe/London"))
How would I replace this? It says dependency injection on the migration guide, but I thought dependency injection was for getting access to classes/variables, not for executing a method
You can add:
class Module extends AbstractModule with ScalaModule {
override def configure():Unit = {
// do your default worf here
}
}
You can use this in place of Global Settings. This is the first thing to get executed bydefault when your application runs.

How to use configuration in scala play 2.5.8 in an object

I am migrating from play 2.4.x to play 2.5.8
While migrating I am getting a lot of deprecation related warning that I am trying to resolve. Once such error is method current in object Play is deprecated: This is a static reference to application, use DI instead
below is the object
object Foo{
def testURL= {
val test = Play.current.configuration.getString("test.url")
}
If I try to use config = Configuration.load() I get the error overloaded method value load with alternatives:
(environment: play.api.Environment)play.api.Configuration
(environment: play.api.Environment,devSettings:
Map[String,AnyRef])play.api.Configuration cannot be applied to ()
I there a way to use the play.api.configuration here ? I don't want to convert object into singleton class.
I'm basing this answer on this group post because it's about as good an answer as you'll get for this topic.
What you're trying to do is an anti-pattern, because something is an object it should not depend on external state. Technically, configuration is based on the state of a file on the filesystem, so it is state in that sense.
To do this cleanly, you should use a class.

How do I create thread pools in Play 2.5.x?

I am currently on Play 2.4.2 and have successfully created thread pools using the following below:
package threads
import scala.concurrent.ExecutionContext
import play.api.libs.concurrent.Akka
import play.api.Play.current
object Contexts {
implicit val db: ExecutionContext = Akka.system.dispatchers.lookup("contexts.db-context")
implicit val pdf: ExecutionContext = Akka.system.dispatchers.lookup("contexts.pdf-context")
implicit val email: ExecutionContext = Akka.system.dispatchers.lookup("contexts.email-context")
}
and then in the code with...
Future{....}(threads.Contexts.db)
We are ready to upgrade to Play 2.5 and having trouble understanding the documentation. The documentation for 2.4.2 uses Akka.system.dispatchers.lookup, which we use without issue. The documentation for 2.5.x uses app.actorSystem.dispatchers.lookup. As far as I know, I have to inject the app into a Class, not an Object. Yet the documentation clearly uses an Object for the example!
Has anyone successfully created thread pools in Play 2.5.x that can help out? Is it as simple as changing Contexts to a class, then injecting it wherever I would like to use this threading? Seems odd since to use the default ExecutionContext I just have to make an implicit import.
Also, we are using Play scala.
If you simply change your Contexts to a class, then you will have to deal with how to get an instance of that class.
In my opinion, if you have a number of thread pools that you want to make use of, named bindings are the way to go. In the below example, I will show you how you could accomplish this with guice.
Note that guice injects depedencies at runtime, but it is also possible to inject dependencies at compile time.
I'm going to show it with the db context as an example. First, this is how you will be using it:
class MyService #Inject() (#Named("db") dbCtx: ExecutionContext) {
// make db access here
}
And here's how you could define the binding:
bind[ExecutionContext].qualifiedWith("db").toProvider[DbExecutionContextProvider]
And somewhere define the provider:
class DbExecutionContextProvider #Inject() (actorSystem: ActorSystem) extends Provider[ExecutionContext] {
override def get(): ExecutionContext = actorSystem.dispatchers.lookup("contexts.db-context")
}
You will have to do this for each of your contexts. I understand this may be a little cumbersome and there may actually be more elegant ways to define the bindings in guice.
Note that I have not tried this out. One issue you might stumble upon could be that you'll end up with conflicts, because play already defines a binding for the ExecutionContext in their BuiltinModule. You may need to override the binding to work around that.

Play 2.5.X dependency injection

I am upgrading play framework app from 2.4.6 to 2.5.x.
There are several occurrences where I call helper methods which belongs to some object. These helper methods use play's built-in classes(for example play.api.Play.current.configuration.underlying.getString) to get the job done.
I get following warning: "method current in object Play is deprecated: This is a static reference to application, use DI instead"
If I face this problem in class method then I can use dependency injection. How to deal with such a situation where method belongs to object and I am warned to use DI?
Play Framework usually provides a class you can inject instead of using the old static references.
For example, the below would mean you can stop using Play.current.configuration and DB:
import javax.inject.Inject
import play.api.db.Database
import play.api.Configuration
class MyClass #Inject() (configuration: Configuration, db: Database) {
...
}

Using Mockito in GWT project

I am new to using Mockito and I am running through an example test class written in our GWT project.
At some places ,in order to get a Mock we used Mockito.mock(SecurityDao.class)
but in other places in the same test class we instantiated other classes using the "new" keyword.
I think that in order to mock a class i need to pass in the interface as the parameter to Mockito.mock ,and if my class does not implement an interface then i need to use the "new" keyword to instantiate the class.
Is this correct?When should i really use Mockito.mock??
Thanks
Always use Mockito#mock() when creating an object other than that under test. Mockito can create mocks for interfaces and classes.