I am currently trying to set up a Play2 application with dependency injection, with information from the official docs. However, my IDE cannot find GuiceApplicationBuilder. So which additional entry for libraryDependencies do I have to specify to get this builder?
EDIT: I made a screenshot of what happens when I try to import the things stated by #anquegi
EDIT 2: The problem was very simple: I used the wrong version of Play - 2.3.8 did in fact not have these, I had to use 2.4.0-RC2 to get it to work.
At the dependencies in the play docs /ScalaDependencyInjection you must import this
import play.api.ApplicationLoader
import play.api.Configuration
import play.api.inject._
import play.api.inject.guice._
This is the compile code in the section Advanced: Extending the GuiceApplicationLoader, so you need to use this extending in your class:
import play.api.ApplicationLoader
import play.api.Configuration
import play.api.inject._
import play.api.inject.guice._
class CustomApplicationLoader extends GuiceApplicationLoader() {
override def builder(context: ApplicationLoader.Context): GuiceApplicationBuilder = {
val extra = Configuration("a" -> 1)
initialBuilder
.in(context.environment)
.loadConfig(extra ++ context.initialConfiguration)
.overrides(overrides(context): _*)
}
}
Related
My project was recently updated from Play 2.5 to 2.6.13.
I added a new script 16.sql but the change were not applied in the table play_evolutions
According to the documentation 2.6, the EvolutionsComponents have to be injected if you use compile time DI. But Guice is runtime DI, so I should not have to inject any components.
I enabled the evolutions in the build.sbt
libraryDependencies ++= Seq(evolutions, jdbc)
In application.conf
play.evolutions.enabled=true
play.evolutions.autoApply=true
What is my project missing ? Any git examples are welcome
I solved it by following the documentation since upgrading to Play 2.6
Here is my code
import play.api.ApplicationLoader.Context
import play.api.{Application, ApplicationLoader, BuiltInComponentsFromContext}
import play.api.db.{DBComponents, HikariCPComponents}
import play.api.db.evolutions.EvolutionsComponents
import play.api.routing.Router
import play.filters.HttpFiltersComponents
import router.Routes
class MyApplicationLoader extends ApplicationLoader {
def load(context: ApplicationLoader.Context): Application = {
new AppComponents(context).application
}
}
class AppComponents(context: Context)
extends BuiltInComponentsFromContext(context)
with DBComponents
with EvolutionsComponents
with HikariCPComponents
with HttpFiltersComponents {
// this will actually run the database migrations on startup
applicationEvolutions
// val prefix: String = "/"
lazy val router = Router.empty
// lazy val router: Router = bind(classOf[Routes]).to(classOf[Routes])
}
And in the conf/application.conf, add this line
play.application.loader=MyApplicationLoader
Completely new to Cassandra. Tried to initialize a database in Cassandra using phantom-dsl. I received this error message.
*** RUN ABORTED ***
java.lang.AssertionError: assertion failed: no symbol could be loaded from class com.datastax.driver.core.Cluster in package core with name Cluster and classloader sun.misc.Launcher$AppClassLoader#279f2327
at scala.reflect.runtime.JavaMirrors$JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$classToScala1(JavaMirrors.scala:1021)
at scala.reflect.runtime.JavaMirrors$JavaMirror$$anonfun$classToScala$1.apply(JavaMirrors.scala:980)
at scala.reflect.runtime.JavaMirrors$JavaMirror$$anonfun$classToScala$1.apply(JavaMirrors.scala:980)
at scala.reflect.runtime.JavaMirrors$JavaMirror$$anonfun$toScala$1.apply(JavaMirrors.scala:97)
at scala.reflect.runtime.TwoWayCaches$TwoWayCache$$anonfun$toScala$1.apply(TwoWayCaches.scala:39)
at scala.reflect.runtime.Gil$class.gilSynchronized(Gil.scala:19)
at scala.reflect.runtime.JavaUniverse.gilSynchronized(JavaUniverse.scala:16)
at scala.reflect.runtime.TwoWayCaches$TwoWayCache.toScala(TwoWayCaches.scala:34)
at scala.reflect.runtime.JavaMirrors$JavaMirror.toScala(JavaMirrors.scala:95)
at scala.reflect.runtime.JavaMirrors$JavaMirror.classToScala(JavaMirrors.scala:980)
I am not really sure whether it is an issue with the Connector in phantom-dsl or the ClusterBuilder in datastax-driver.
Connector.scala
package com.neruti.db
import com.neruti.db.models._
import com.websudos.phantom.database.Database
import com.websudos.phantom.connectors.ContactPoints
import com.websudos.phantom.dsl.KeySpaceDef
object Connector {
val host= Seq("localhost")
val port = 9160
val keySpace: String = "nrt_entities"
// val inet = InetAddress.getByName
lazy val connector = ContactPoints(host,port).withClusterBuilder(
_.withCredentials("cassandra", "cassandra")
).keySpace(keySpace)
}
CassandraSpec.scala
package com.neruti.db
import com.neruti.User
import com.neruti.db.models._
import com.neruti.db.databases._
import com.neruti.db.services._
import com.neruti.db.Connector._
import java.util.UUID
import com.datastax.driver.core.ResultSet
import org.scalatest._
import org.scalatest.{BeforeAndAfterAll,FlatSpec,Matchers,ShouldMatchers}
import org.scalatest.concurrent.ScalaFutures
import org.scalamock.scalatest.MockFactory
import scala.concurrent.duration._
import scala.concurrent.{Await, Future}
import scala.concurrent.ExecutionContext.Implicits.global
abstract class BaseCassandraSpec extends FlatSpec
with BeforeAndAfterAll
with Inspectors
with Matchers
with OptionValues
with ScalaFutures
class CassandraTest extends BaseCassandraSpec
with ProductionDatabase
with UserService
with Connector.connector.Connector{
val user = User(
Some("foobar"),
Some("foo#foobar.com"),
Some(UUID.randomUUID()),
)
override protected def beforeAll(): Unit = {
Await.result(database.userModel.create(user),10.seconds)
}
}
Looks there may be multiple issues you are looking at:
The latest version of phantom is 2.1.3, I'd strongly recommend using that, especially if you are just starting out. The migration guide is here in case you need it.
The entire reflection mechanism has been replaced in the latest version, so that error should magically go away. With respect to testing and generating objects, I would also look to include com.outworkers.util.testing, which is freely available on Maven Central
libraryDependencies ++= Seq(
//..,
"com.outworkers" %% "phantom-dsl" % "2.1.3",
"com.outworkers" %% "util-testing" % "0.30.1" % Test
)
This will offer you automated case class generation:
import com.outworkers.util.testing._
val sample = gen[User]
I'm having a problem with a migration to Play 2.5 with Scala. I had to start using DependencyInjection and after reading all the Play Framework 2.5 migration documentation and making all the corresponding implementations I arrived to an strange problem. Play indicates that class Routes should be automatically generated with the new DependencyInjection schema but when I tried to import the class in my custom ApplicationLoader, the compiler tells me that cannot resolve symbol "router". Below is part of my code, hope you can help me with this, thanks!
import controllers.Assets
import controllers.api.clients.ClientsController
import play.api.ApplicationLoader.Context
import play.api._
import play.api.libs.ws.ahc.AhcWSComponents
import router.Routes
class AppLoader extends ApplicationLoader {
def load(context: Context) = {
LoggerConfigurator(context.environment.classLoader).foreach {
_.configure(context.environment)
}
new AppComponents(context).application
}
}
class AppComponents(context: Context) extends BuiltInComponentsFromContext(context) with AhcWSComponents {
lazy val clientsController: ClientsController = new ClientsController(wsClient)
lazy val assets: Assets = new Assets(httpErrorHandler)
lazy val router = new Routes(
httpErrorHandler,
clientsController,
assets
)
}
Check the following:
Make sure your build.sbt contains routesGenerator := InjectedRoutesGenerator
Execute playCompileEverything in sbt and refresh your project in your IDE
I´m developing a Play Framework project in Scala, but I not able to get correctly the import controllers.Application reference.
The snippet bellow focus on the onStart method at my Global.scala file, that is located inside the app directory. What is going under the hood? Why can´t I get this easy import done correctly?
import play.api._
import play.api.libs.concurrent.Execution.Implicits._
import play.api.libs.concurrent._
import play.api.Play.current
import scala.concurrent.duration._
import scala.util.Random
import model.StatusUpdate
object Global extends GlobalSettings {
override def onStart(app: Application) {
import controllers.{Application => App}
// Definition of the onStart method.
}
My Application.scala file that is located in the controllers directory is defined as bellow:
package controllers
import play.api._
import play.api.libs.iteratee._
import play.api.libs.json._
import play.api.mvc._
object Application extends Controller {
//Definition of methods
}
I'm new to Scala and Dispatch, and I can't seem to get a basic Post request working.
I'm actually building a sbt plugin that uploads files to a third party service.
Here is my build.sbt file:
sbtPlugin := true
name := "sbt-sweet-plugin"
organization := "com.mattwalters"
version := "0.0.1-SNAPSHOT"
libraryDependencies += "net.databinder.dispatch" %% "dispatch-core" % "0.11.0"
And here is the plugin's SweetPlugin.scala:
package com.mattwalters
import sbt._
import Keys._
import dispatch._
object SweetPlugin extends Plugin {
import SweetKeys._
object SweetKeys {
lazy val sweetApiToken =
SettingKey[String]("Required. Find yours at https://example.com/account/#api")
lazy val someOtherToken =
SettingKey[String]("Required. Find yours at https://example.com/some/other/token/")
lazy val sweetFile =
SettingKey[String]("Required. File data")
lazy val sweetotes =
SettingKey[String]("Required. Release notes")
lazy val sweetUpload =
TaskKey[Unit]("sweetUpload", "A task to upload the specified sweet file.")
}
override lazy val settings = Seq (
sweetNotes := "some default notes",
// define the upload task
sweetUpload <<= (
sweetApiToken,
someOtherToken,
sweetFile,
sweetNotes
) map { (
sweetApiToken,
someOtherToken,
sweetFile,
sweetNotes
) =>
// define http stuff here
val request = :/("www.example.com") / "some" / "random" / "endpoint"
val post = request.POST
post.addParameter("api_token", sweetApiToken)
post.addParameter("some_other_token", someOtherToken)
post.addParameter("file", io.Source.fromFile(sweetFile).mkString)
post.addParameter("notes", sweetNotes)
val responseFuture = Http(post OK as.String)
val response = responseFuture()
println(response) // see if we can get something at all....
}
)
}
The dispatch documentation shows:
import dispatch._, Defaults._
but I get
reference to Defaults is ambiguous;
[error] it is imported twice in the same scope by
removing , Defaults._ makes this error go away.
I also tried the recommendation from this post:
import dispatch._
Import dispatch.Default._
But alas I get:
object Default is not a member of package dispatch
[error] import dispatch.Default._
Also tried the advice from
Passing implicit ExecutionContext to contained objects/called methods:
import concurrent._
import concurrent.duration._
But I still get
Cannot find an implicit ExecutionContext, either require one yourself or import ExecutionContext.Implicits.global
Back to square one...
New to scala so any advice at all on the code above is appreciated.
Since the recommended sbt console run works fine, it looks like one of your other imports also has a Defaults module. It's a standard approach in Scala for collecting implicit values to be used as function params (another naming convention is Implicits).
The other problem is that there is a typo/out-of-date problem in the import statement you got from Google Groups - it's Defaults, plural.
In summary - the best solution is to explicitly let Scala know which module you want to use:
import dispatch._
import dispatch.Defaults._
In the general case, only if the library's docs don't say otherwise: the last error message is pretty common to concurrent programming in Scala. To quote the relevant part:
either require one yourself or import ExecutionContext.Implicits.global
So, unless you want to roll your own ExecutionContext, just import the scala.concurrent.ExecutionContext.Implicits.global one via the scala.concurrent.ExecutionContext.Implicits module.