PLAY Framework Integrating with Akka - scala

I'm trying to get this tutorial to work but they seem to have an issue. I get an error in this piece of code:
(helloActor ? SayHello(name)).mapTo[String].map { message => Ok(message) }
not found: value SayHello
It seems that SayHello(name) is not in the scope of the Application class.

You need to import the SayHello class. Since the class is defined in the companion object of HelloActor, it is not visible by default outside that object.

Related

Can't create ArmeriaCatsBackend in IOApp with Cats effects?

I want to use ArmeriaCatsBackend as sttp backend with Cats effects.
The following code does not compile:
object Main extends IOApp {
val backend = ArmeriaCatsBackend[IO]()
// ...
}
could not find implicit value for evidence parameter of type cats.effect.kernel.Async[cats.effect.IO]
Error occurred in an application involving default arguments.
Documentation
What am I missing?
Dang. I was using scala-effects v2.x and sttp-ameria for v3.
After upgrading to scala-effects v3.x everything is ok.

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 to get application.conf variable in an object using Scala and Play 2.5.x?

I used to get the application.conf variable in Play 2.4.x with Play.current.configuration.getString('NAME_HERE'), and it was working good in class, object and companion object too.
Now, I'm using Play 2.5.4 with Scala in a new project, and I won't use this Play.current, because it's deprecated, but there is an alternative using DI, like this :
class HomeController #Inject() (configuration: play.api.Configuration) extends Controller {
def config = Action {
Ok(configuration.underlying.getString("db.driver"))
}
}
This DI Injection works like a charm in class, but in this project, I need to get the variable db.driver in a object? And as far I know, with an object I can't use DI.
Maybe using Guice would help?
You can use #Singleton annotated class instead of object
trait Foo {}
#Singleton
class FooImpl #Inject()(configuration: play.api.Configuration)) extends Foo {
//do whatever you want
}
#Singleton makes the class singleton.It feels bit awkward because Scala itself natively have syntax object to create a singleton, But this is the easiest and probably best solution to DI into a singleton.
You also may create the singleton eagerly like the code below.
bind(classOf[Foo]).to(classOf[FooImpl])asEagerSingleton()
for more detail Info, You can look up Google Guice Wiki and Playframework site
EDIT
How you call it is exactly the same as how you DI in Playframework2.5.
class BarController #Inject()(foo: Foo) extends Controller {
//Do whatever you want with Foo
}
Guice basically generates new instance every time you DI, Once you put #Singleton, Guice use only one instance instead.
DI is for anti-high coupling.So when you want to use a class you defined from another class,You need to DI otherwise the classes are highly coupled which end up making it harder to code your unit test.
FYI, You can use them outside of Play with this technique.
Create an Instance of class which does DI via Playframework Guice Independently in Scala
Have you tried
import com.typesafe.config.ConfigFactory
val myConfig = ConfigFactory.load().getString("myConfig.key")
Above approach doesn't require you to convert your object to singleton class.
You can do
Play.current.configuration
however that will (probably) no longer be possible with Play 2.6.
Ideally, however, you would pass the configuration in as a parameter to that method of the object or, use a class instead of an object.
What I somtimes do to migrate 'from object to class':
class MyComponent #Inject() (config: Configuration) {
// here goes everything nice
def doStuff = ???
}
object MyComponent {
#deprecated("Inject MyComponent")
def doStuff = {
val instance = Play.current.injector.instanceOf[MyComponent]
instance.doStuff
}
}
This way, you're not breaking existing code while all users of your methods can slowly migrate to using classes.

scala selenium dsl page object

I am using the Selenium dsl and would like to use a Page object. Currently however it seems I have to define the page object inside the test class. The reason I would want a page object is to share common features between tests so this seems a bit pointless... Has anyone been using the page object model with Selenium DSL? What is the idea behind defining the page object in the same class? How come I get a compiler error if I define the page object outside of the test class. Am I doing something wrong?
The compiler error I get is:
Expected MySpec.this.type#Page, actual: MyPage
You can define the class outside of the test class like this:
class TwitterPage {
val url = "http://twitter.com"
}
Then, use it inside the test by mixing in the Page trait:
val page = new TwitterPage with Page
go to page
title should be ("Welcome to Twitter")
This compiled and worked just fine for me.

Scala object struggles with Java Class.newInstance()

UPDATE:
I have somewhat resolved the issue. Just in case if anyone runs in the same problem, here is the simplest solution: Looking at the MTApplcation source code, I have discovered that the initialize() method can be overloaded, taking a String parameter for the name of the class to instantiate. So if I create a separate class that extends MTApplication and pass it's name there, everything works correctly.
END OF UPDATE
I have a situation in Scala while trying to use a java library (MT4j, which is based on Processing). The library wants to instantiate the main class of the app (the caller-class):
Class<?> c = Thread.currentThread().getContextClassLoader().loadClass(name);
applet = (PApplet) c.newInstance();
So as to refer it later in it's works.
However, it fails because, I guess, the main Scala class is not a class, but an object and due to library structure, it is necessary to call a static method initialize() of the main library class MTApplication. In Java static fields are located in classes, but in Scala - in objects. So it is impossible to instantiate an object and the library fails. In contrast to MT4j, Processing itself makes no calls to static methods on startup and successfully passes that phase.
If I just create a companion class, everything works fine except that the companion class does not get its fields initialized because the static initialize() method is called in companion object, the class instance just gets dead-born and the library becomes unusable.
At least that is how I understand this problem.
I get this error:
Exception in thread "main" java.lang.RuntimeException: java.lang.IllegalAccessException: Class processing.core.PApplet can not access a member of class main.Main$ with modifiers "private"
at processing.core.PApplet.runSketch(PApplet.java:9103)
at processing.core.PApplet.main(PApplet.java:9292)
at org.mt4j.MTApplication.initialize(MTApplication.java:311)
at org.mt4j.MTApplication.initialize(MTApplication.java:263)
at org.mt4j.MTApplication.initialize(MTApplication.java:254)
at main.Main$.main(Main.scala:26)
at main.Main.main(Main.scala)
It is hard for me to explain also because I do not fully understand what is going on here. But anyone who has these libs can reproduce the situation in a couple of minutes, trying to launch the main class.
The abstract startUp() method which should be implemented to start the app, makes everything look even more sad. It initializes the object, but what the library tries to work with is an instance of the companion class which does not get initialized because in Scala the method belongs to the object.
My code:
object Main extends MTApplication {
def main(args: Array[String]) {
MTApplication.initialize()
new Main().startUp()
}
//this method is abstarct so it MUST be implemented,
override def startUp(){
}
}
class Main extends MTApplication {
override def startUp(){
//startup here
}
}
I am sorry if my explanations are vague, I just do not get it all completely. Probably to understand it is easier to repeat the experiment with MT4j library with Processing source code instead of the pre-linked 'core.jar' there to see what is happening inside. Doeas anyone have ideas on any workaround here?
Problem solved. Here is the solution:
object Main {
var current: MainC = _
def main(args: Array[String]) {
MTApplication.initialize("org.mttablescreen.main.MainC")
}
}
class MainC extends MTApplication {
//cons
Main.current = this
//cons ends
override def startUp(){
prepare
}
def prepare () {...}
}