A Scala console is very handy when you're working on a Scala project. The same console is available in our Play application's console as well. All that we need to do to get the Scala console is execute the console
command in our application console:
[app]$ console [info] Compiling 3 Scala sources to /home/app/target/scala-2.10/classes... [info] Starting scala interpreter... [info] Welcome to Scala version 2.10.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_60). Type in expressions to have them evaluated. Type :help for more information. scala>
However, we can only call methods from
models or
utils. If classes or objects within these packages utilize Play.application.configuration
or attempt to fetch data from the DB or some other Play utils, we will not be able to instantiate them. This is because most of the Play components require access to an instance of the currently running Play application. Importing play.api.Play.current
makes this possible but not entirely; we still need a running application, which will be marked as the current application.
Let's create an application and start it from the Scala console, and then import play.api.Play.current
:
scala> :pas // Entering paste mode (ctrl-D to finish) import play.api.Play val application = new DefaultApplication(new java.io.File("."), this.getClass.getClassLoader, None, Mode.Dev) Play.start(application) import play.api.Play.current
Once we exit paste mode, the code will be interpreted and the application will be started. We can see this from this output:
// Exiting paste mode, now interpreting. SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/home/.ivy2/cache/ch.qos.logback/logback-classic/jars/logback-classic-1.1.1.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/home/.ivy2/cache/org.slf4j/slf4j-log4j12/jars/slf4j-log4j12-1.7.2.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder] [info] play - Application started (Dev) import play.api.Play application: play.api.DefaultApplication = play.api.DefaultApplication@29600952 import play.api.Play.current scala>
Now, we can view the configuration, view or modify data, and so on. For example, let's try to get the application's configuration:
scala> Play.application.configuration res7: play.api.Configuration = Configuration(Config(SimpleConfigObject({"akka":{"actor":{"creation-timeout":"20s","debug":{"autoreceive":"off","event-stream":"off","fsm":"off","lifecycle":"off","receive":"off","router-misconfiguration":"off","unhandled":"off"},"default-dispatcher":{"attempt-teamwork":"on","default-executor":{"fallback":"fork-join-executor"},"executor":"default-executor","fork-join-executor":{"parallelism-factor":3,"parallelism-max":64,"parallelism-min":8},"mailbox-requirement":"","shutdown-timeout":"1s","thread-pool-executor":{"allow-core-timeout":"on","core-pool-size-factor":3,"core-pool-size-max":64,"core-pool-size-min":8,"keep-alive-time":"60s","max-pool-size-factor":3,"max-pool-size-max":64,"max-pool-size-min":8,"task-queue-size":-1,"task-queue-type":"linked"},"thro...
Nice, isn't it? Yet, this is not enough if we want to call actions and check results for different inputs. For such cases, we shouldn't use the console
command, but instead, the test:console
command:
[app] $ test:console [info] Starting scala interpreter... [info] Welcome to Scala version 2.10.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_60). Type in expressions to have them evaluated. Type :help for more information. scala> :pas // Entering paste mode (ctrl-D to finish) import play.api.test.Helpers._ import play.api.test._ import play.api.Play val application = FakeApplication() Play.start(application) import play.api.Play.current // Exiting paste mode, now interpreting. …
Now, from this Scala console, we can view the configuration, modify data, as well as call an action:
scala> Play.application.configuration res0: play.api.Configuration = Configuration(Config(SimpleConfigObject({"akka":{"actor":{"creation-timeout":"20s","debug":{"autoreceive":"off","event-stream":"off","fsm":"off","lifecycle":"off","receive":"off","router-misconfiguration":"off","unhandled":"off"},"default-dispatcher":{"attempt-teamwork":"on","default-executor":{"fallback":"fork-join-executor"},"executor":"default-executor","fork-join-executor":{"parallelism-factor":3,"parallelism-max":64,"parallelism-min":8},"mailbox-requirement":"","shutdown-timeout":"1s","thread-pool-executor":{"allow-core-timeout":"on","core-pool-size-factor":3,"core-pool-size-max":64,"core-pool-size-min":8,"keep-alive-time":"60s","max-pool-size-factor":3,"max-pool-size-max":64,"max-pool-size-min":8,"task-queue-size":-1,"task-queue-type":"linked"},"thro... scala> controllers.Application.index("John").apply(FakeRequest()) res1: scala.concurrent.Future[play.api.mvc.Result] = scala.concurrent.impl.Promise$KeptPromise@6fbd57ac scala> contentAsString(res1) res2: String = Hello John
3.143.235.219