Injecting the current App in Play 2.5.2 - scala

I am using the DI to access my App in Play 2.5:
import com.google.inject.{Inject, Provider}
import play.api.mvc._
import play.api.Application
class ApplicationController #Inject()(p: Provider[Application]) extends Controller {
implicit lazy val app = p.get()
println(app.hashCode()+"") // Random line to use the injected app
}
I am getting the following error :
ProvisionException: Unable to provision, see the following errors:
1) Tried proxying play.api.Application to support a circular dependency, but circular proxies are disabled. ...
I went on the Play Migration guide : https://www.playframework.com/documentation/2.5.x/Migration25#Handling-legacy-components
and did as they say to avoid circular dependency, however I still have that error.
I've also found a variable called disableCircularProxies which I am not currently using (http://google.github.io/guice/api-docs/latest/api-diffs/changes/docdiffs_com.google.inject.html) as I am not sure how to do so and found very little info about it.
Any idea how to solve this circular dependency error ?
Here is the full stack trace :
Tried proxying play.api.Application to support a circular dependency, but circular proxies are disabled.
at play.api.DefaultApplication.class(Application.scala:221)
while locating play.api.DefaultApplication
while locating play.api.Application
at myCustomProject.controllers.ApplicationController.<init>(ApplicationController.scala:9)
while locating myCustomProject.controllers.ApplicationController
for parameter 1 at router.Routes.<init>(Routes.scala:31)
while locating router.Routes
while locating play.api.inject.RoutesProvider
while locating play.api.routing.Router
for parameter 0 at play.api.http.JavaCompatibleHttpRequestHandler.<init>(HttpRequestHandler.scala:200)
while locating play.api.http.JavaCompatibleHttpRequestHandler
while locating play.api.http.HttpRequestHandler
for parameter 4 at play.api.DefaultApplication.<init>(Application.scala:221)
at play.api.DefaultApplication.class(Application.scala:221)
while locating play.api.DefaultApplication
while locating play.api.Application
Ultimately, I shouldn't be using this Provider[Application] but rather the configuration, environment, ... from the App.
It's just that according to the doc, I should be able to have that working.

Java Version:
#Inject
private Provider<Application> application;
private void someMethod {
...
application.get();
}

Related

All connection pools fail to initialize when one connection pool fails to initialize

Is it a bug?
I am using Playframework 2.6.6 with scala 2.12.3. I have 3 databases defined in application.conf ( the settings for the hikaricp connection pools are all over the map because I experimented with them):
db {
mentions {
driver="org.postgresql.Driver"
url="jdbc:postgresql://localhost:5432/mentions"
password="***"
username="play"
hikaricp {
maximumPoolSize = 2
minimumIdle=2
}
}
postgres {
driver="org.postgresql.Driver"
url="jdbc:postgresql://localhost:5432/postgres"
password="***"
username="postgres"
hikaricp {
maximumPoolSize = 9
minimumIdle=9
}
}
sqlserver {
driver="net.sourceforge.jtds.jdbc.Driver"
url="jdbc:jtds:sqlserver://10.211.55.5:1433/db"
username="sa"
password="***"
hikaricp {
maximumPoolSize=4
minimumIdle=4
//connectionTestQuery="select 1"
}
}
}
With this configuration the Hikaricp connection pool fails to initialize the sql server connection pool and actually none of the other two connection pools are initialized. The fix for the sql server connection error is to set the connectionTestQuery. That's not the point of this post. I don't understand why the other two connections fail when this one fails. In my mind the other two connection pools should still function.
Here are the error messages from the console:
[info] application - Creating Pool for datasource 'sqlserver'
[error] c.z.h.p.PoolBase - HikariPool-1 - Failed to execute isValid() for connection, configure connection test query (null).
[info] application - Creating Pool for datasource 'sqlserver'
[error] c.z.h.p.PoolBase - HikariPool-2 - Failed to execute isValid() for connection, configure connection test query (null).
[info] application - Creating Pool for datasource 'sqlserver'
[error] c.z.h.p.PoolBase - HikariPool-3 - Failed to execute isValid() for connection, configure connection test query (null).
[error] application -
! #761fipg95 - Internal server error, for (GET) [/] ->
play.api.UnexpectedException: Unexpected exception[CreationException: Unable to create injector, see the following errors:
1) Error injecting method, java.lang.AbstractMethodError
at com.google.inject.util.Providers$GuicifiedProviderWithDependencies.initialize(Providers.java:149)
at play.api.db.DBModule$$anonfun$$lessinit$greater$1.$anonfun$new$1(DBModule.scala:25):
Binding(interface play.api.db.Database qualified with QualifierInstance(#play.db.NamedDatabase(value=sqlserver)) to ProviderTarget(play.api.db.NamedDatabaseProvider#65c05a8b)) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
2) Error injecting method, java.lang.AbstractMethodError
at com.google.inject.util.Providers$GuicifiedProviderWithDependencies.initialize(Providers.java:149)
at play.api.db.DBModule$$anonfun$$lessinit$greater$1.$anonfun$new$1(DBModule.scala:25):
Binding(interface play.api.db.Database qualified with QualifierInstance(#play.db.NamedDatabase(value=mentions)) to ProviderTarget(play.api.db.NamedDatabaseProvider#700c1d35)) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
3) Error injecting method, java.lang.AbstractMethodError
at com.google.inject.util.Providers$GuicifiedProviderWithDependencies.initialize(Providers.java:149)
at play.api.db.DBModule$$anonfun$$lessinit$greater$1.$anonfun$new$1(DBModule.scala:25):
Binding(interface play.api.db.Database qualified with QualifierInstance(#play.db.NamedDatabase(value=postgres)) to ProviderTarget(play.api.db.NamedDatabaseProvider#1f4f0047)) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
3 errors]
at play.core.server.DevServerStart$$anon$1.reload(DevServerStart.scala:186)
at play.core.server.DevServerStart$$anon$1.get(DevServerStart.scala:124)
at play.core.server.AkkaHttpServer.modelConversion(AkkaHttpServer.scala:183)
at play.core.server.AkkaHttpServer.handleRequest(AkkaHttpServer.scala:189)
at play.core.server.AkkaHttpServer.$anonfun$createServerBinding$3(AkkaHttpServer.scala:106)
at akka.stream.impl.fusing.MapAsync$$anon$23.onPush(Ops.scala:1172)
at akka.stream.impl.fusing.GraphInterpreter.processPush(GraphInterpreter.scala:499)
at akka.stream.impl.fusing.GraphInterpreter.processEvent(GraphInterpreter.scala:462)
at akka.stream.impl.fusing.GraphInterpreter.execute(GraphInterpreter.scala:368)
at akka.stream.impl.fusing.GraphInterpreterShell.runBatch(ActorGraphInterpreter.scala:571)
Caused by: com.google.inject.CreationException: Unable to create injector, see the following errors:
1) Error injecting method, java.lang.AbstractMethodError
at com.google.inject.util.Providers$GuicifiedProviderWithDependencies.initialize(Providers.java:149)
at play.api.db.DBModule$$anonfun$$lessinit$greater$1.$anonfun$new$1(DBModule.scala:25):
Binding(interface play.api.db.Database qualified with QualifierInstance(#play.db.NamedDatabase(value=sqlserver)) to ProviderTarget(play.api.db.NamedDatabaseProvider#65c05a8b)) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
2) Error injecting method, java.lang.AbstractMethodError
at com.google.inject.util.Providers$GuicifiedProviderWithDependencies.initialize(Providers.java:149)
at play.api.db.DBModule$$anonfun$$lessinit$greater$1.$anonfun$new$1(DBModule.scala:25):
Binding(interface play.api.db.Database qualified with QualifierInstance(#play.db.NamedDatabase(value=mentions)) to ProviderTarget(play.api.db.NamedDatabaseProvider#700c1d35)) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
3) Error injecting method, java.lang.AbstractMethodError
at com.google.inject.util.Providers$GuicifiedProviderWithDependencies.initialize(Providers.java:149)
at play.api.db.DBModule$$anonfun$$lessinit$greater$1.$anonfun$new$1(DBModule.scala:25):
Binding(interface play.api.db.Database qualified with QualifierInstance(#play.db.NamedDatabase(value=postgres)) to ProviderTarget(play.api.db.NamedDatabaseProvider#1f4f0047)) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
3 errors
at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:470)
at com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:176)
at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:110)
at com.google.inject.Guice.createInjector(Guice.java:99)
at com.google.inject.Guice.createInjector(Guice.java:84)
at play.api.inject.guice.GuiceBuilder.injector(GuiceInjectorBuilder.scala:185)
at play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:137)
at play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21)
at play.core.server.DevServerStart$$anon$1.$anonfun$reload$3(DevServerStart.scala:174)
at play.utils.Threads$.withContextClassLoader(Threads.scala:21)
Caused by: java.lang.AbstractMethodError: null
at net.sourceforge.jtds.jdbc.JtdsConnection.isValid(JtdsConnection.java:2833)
at com.zaxxer.hikari.pool.PoolBase.checkDriverSupport(PoolBase.java:456)
at com.zaxxer.hikari.pool.PoolBase.setupConnection(PoolBase.java:423)
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:381)
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:205)
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:448)
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:519)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:113)
at com.zaxxer.hikari.HikariDataSource.<init>(HikariDataSource.java:72)
at play.api.db.HikariCPConnectionPool.$anonfun$create$1(HikariCPModule.scala:51)
An update: I still think that architecturally, if one connection pool doesn't work, the other connections pools should not be affected. Today I shutdown my windows vm running sql server and I had only my postgresql server running. The page I tested connected only to the postgresql dbs and it still failed because the sql server connect pool didn't work. This time it failed with a configuration error java.sql.SQLException - Login Timed out.
After doing some debugging in 2.6.6 & 2.6.7, I discovered the following:
java.lang.AbstractMethodError inherits java.lang.IncompatibleClassChangeError which inherits java.lang.LinkageError. java.lang.LinkageError is considered fatal according to the NonFatal object:
object NonFatal {
/**
* Returns true if the provided `Throwable` is to be considered non-fatal, or false if it is to be considered fatal
*/
def apply(t: Throwable): Boolean = t match {
// VirtualMachineError includes OutOfMemoryError and other fatal errors
case _: VirtualMachineError | _: ThreadDeath | _: InterruptedException | _: LinkageError | _: ControlThrowable => false
case _ => true
}
/**
* Returns Some(t) if NonFatal(t) == true, otherwise None
*/
def unapply(t: Throwable): Option[Throwable] = if (apply(t)) Some(t) else None
}
So the Try calls sprinkled all over the code don't catch this exception.
The exception ends up being handled by the guice layers. The call goes back to the guice Initializer.injectAll method which (among other objects) injects the NamedDatabaseProvider objects for each database connection configured in the application.conf file (the binding to the NamedDatabaseProvider is wired in the the DBModule). The NamedDatabaseProvider objects depend on DBApi whose initialization fails every time due to the AbstractMethodError exception which is considered fatal.
Ultimately the problem is a combination of circumstances: 1. the exception throws in the Hikaricp code is fatal, 2. The DBApi code wants to initialize all connection pools and it doesn't handle fatal errors.
I don't consider this a bug. Perhaps the Hickaricp dudes could have thrown an UnsupportedOperationException or something similar.
For others interested I found this: https://github.com/njlg/playdb.

No Runnable Methods and Test Class Should Have Exactly One Public Constructor Exception

I can't seem to shake this error. The Eclipse Runner appears to find the #Test annotations however the BlockJUnit4ClassRunner validateConstructor and validateInstanceMethods can't see the #Test annotations.
I have read In this case, Test.class have been loaded with the system ClassLoader (i.e. the one that loaded JUnitCore), therefore technically none of the test methods will have been annotated with that annotation.
Solution is to load JUnitCore in the same ClassLoader as the tests themselves.
I've tried updating the JUnitCore in the same ClassLoader however missed the exact configuration. I have also tried an external runner along with try/catch to consume the error.. Nothing appears to work.
How would I...
Junit Runner to identify the class,
or
Possibly Ignore this error in a try/catch
or
Implement the correct structure for the ClassLoader solution?
I've attached a copy of code in git repository reference. bhhc.java throws the exception upon execution.
Supported Data:
SRC: https://github.com/agolem2/MavenJunit/blob/master/src/Test/bhhc.java
ERROR:
Google
Completed Test Case bhhc Date: 2017-09-26 08_57_17.318
Test run was NOT successful:
No runnable methods - Trace: java.lang.Exception: No runnable methods
org.junit.runners.BlockJUnit4ClassRunner.validateInstanceMethods(BlockJUnit4Cl
assRunner.java:191)
org.junit.runners.BlockJUnit4ClassRunner.collectInitializationErrors(BlockJUni
t4ClassRunner.java:128)
Test class should have exactly one public constructor - Trace:
java.lang.Exception: Test class should have exactly one public constructor
org.junit.runners.BlockJUnit4ClassRunner.validateOnlyOneConstructor(BlockJUnit
4ClassRunner.java:158)
org.junit.runners.BlockJUnit4ClassRunner.validateConstructor(BlockJUnit4ClassR
unner.java:147)

How do I configure Guice in Play Framework to require an #Inject annotation for empty constructors?

I'd like to prevent Guice in Play Framework (2.5.x) from injecting classes without the #Inject() annotation on the constructor. Guice provides the requireAtInjectOnConstructors configuration option on Binder which achieves this.
The Play documentation describes two ways to customize Guice:
Programmatic Bindings
Extending the GuiceApplicationLoader
I first tried customizing the Binder in my Module$configure method:
import com.google.inject.AbstractModule
class Module extends AbstractModule {
override def configure() = {
binder().requireAtInjectOnConstructors()
}
}
When I then run the application I see the following errors:
! #7115jkk8o - Internal server error, for (GET) [/] ->
play.api.UnexpectedException: Unexpected exception[CreationException: Unable to create injector, see the following errors:
1) Explicit #Inject annotations are required on constructors, but play.api.inject.DefaultApplicationLifecycle has no constructors annotated with #Inject.
at play.api.inject.BuiltinModule.bindings(BuiltinModule.scala:42):
Binding(class play.api.inject.DefaultApplicationLifecycle to self) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
2) Explicit #Inject annotations are required on constructors, but play.api.http.NoHttpFilters has no constructors annotated with #Inject.
at play.utils.Reflect$.bindingsFromConfiguration(Reflect.scala:53):
Binding(interface play.api.http.HttpFilters to ConstructionTarget(class play.api.http.NoHttpFilters)) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
When I extend the GuiceApplicationBuilder to set this configuration:
import play.api.ApplicationLoader
import play.api.inject.guice.{ GuiceApplicationBuilder, GuiceApplicationLoader }
class CustomApplicationLoader extends GuiceApplicationLoader {
override def builder(context: ApplicationLoader.Context): GuiceApplicationBuilder = {
initialBuilder.requireAtInjectOnConstructors()
}
}
I see the same errors with this approach.
The error messages indicate to me that the Play Framework itself relies on Guice injecting classes with empty constructors which are not annotated with #Inject().
Is there a way I can configure Guice to require the #Inject() annotation for classes in my application without affecting the Play Framework Guice configuration?

After upgrade to Play 2.5.0: java.lang.RuntimeException: There is no started application

I tried to update my app to Play 2.5.0. All tests with OneAppPerTest don't run anymore. The app does not run anymore either. I can start the app with sbt run, but my first request brings the same error message:
java.lang.RuntimeException: There is no started application.
I do have a mix with DI and traits and it works properly in play 2.4.6.
I have no clue where to search now. Does anybody has the same problems?
Error injecting constructor, java.lang.RuntimeException: There is no started application
at com.myproject.controllers.MyController.<init>(MyController.scala:30)
at com.myproject.controllers.MyController.class(MyController.scala:30)
while locating com.myproject.controllers.MyController
for parameter 7 at router.Routes.<init>(Routes.scala:79)
while locating router.Routes
while locating play.api.inject.RoutesProvider
while locating play.api.routing.Router
for parameter 0 at play.api.http.JavaCompatibleHttpRequestHandler.<init>(HttpRequestHandler.scala:200)
while locating play.api.http.JavaCompatibleHttpRequestHandler
while locating play.api.http.HttpRequestHandler
for parameter 4 at play.api.DefaultApplication.<init>(Application.scala:220)
at play.api.DefaultApplication.class(Application.scala:220)
while locating play.api.DefaultApplication
while locating play.api.Application
Caused by: java.lang.RuntimeException: There is no started application
at scala.sys.package$.error(package.scala:27)
at play.api.Play$$anonfun$current$1.apply(Play.scala:86)
at play.api.Play$$anonfun$current$1.apply(Play.scala:86)
at scala.Option.getOrElse(Option.scala:121)
at play.api.Play$.current(Play.scala:86)
at com.myproject.model.dao.DAOSlick$class.dbConfig(DAOSlick.scala:11)
at com.myproject.controllers.MyController.dbConfig$lzycompute(MyController.scala:30)
at com.myproject.controllers.MyController.dbConfig(MyController.scala:30)
at play.api.db.slick.HasDatabaseConfig$class.driver(DatabaseConfigProvider.scala:142)
at com.myproject.controllers.MyController.driver$lzycompute(MyController.scala:30)
at com.myproject.controllers.MyController.driver(MyController.scala:30)
at com.myproject.controllers.MyController.driver(MyController.scala:30)
at com.myproject.model.dao.JavaTimeMapper$class.$init$(JavaTimeMapper.scala:20)
at com.myproject.controllers.MyController.<init>(MyController.scala:30)
at com.myproject.controllers.MyController$$FastClassByGuice$$b68ea36a.newInstance(<generated>)
at com.google.inject.internal.cglib.reflect.$FastConstructor.newInstance(FastConstructor.java:40)
Here is my DAOSlick Trait, which is using the deprecated Play.current:
import play.api.Play
import play.api.db.slick.DatabaseConfigProvider
import slick.driver.JdbcProfile
trait DAOSlick {
protected lazy val dbConfig = DatabaseConfigProvider.get[JdbcProfile]("default")(Play.current) // this is line 11, where it fails
protected val driver: JdbcProfile
import driver.api._
}
Here is the head of "MyController":
#Singleton
class WebsocketController #Inject() (redis: RedisService, notificationService: NotificationService) extends SecuredController with SomeService {
Both, the injected Service NotificationService and the Trait SomeService are extending the DAOSlick Trait.
Can anybody give me a hint, how to change the dependency in my DAOSlick to Play.current, please?
Looks like DatabaseConfig via Global Lookup is out of date. Instead of using a global lookup, I suggest to switch to dependency injection altogether:
import javax.inject.Inject
import play.api.db.slick.{DatabaseConfigProvider, HasDatabaseConfigProvider}
import slick.driver.JdbcProfile
class SomeDao #Inject()(protected val dbConfigProvider: DatabaseConfigProvider) extends HasDatabaseConfigProvider[JdbcProfile] {
import driver.api._
// dao stuff...
}
Not sure if global lookup is still a thing anymore... Probably not with the deperecation of Play.current. Please correct me if I'm wrong.

Play Framework For Scala: Compilation error[type Application is not a member of package controllers]

I try to compile a scala example in the book: "Play for Scala" but get a following compilation error on Play console:
C:\Play\exp\ch6_implicits>activator run
[info] Loading project definition from C:\Play\exp\ch6_implicits\project
[info] Set current project to ch6_implicits (in build file:/C:/Play/exp/ch6_implicits/)
--- (Running the application, auto-reloading is enabled) ---
[info] p.a.l.c.ActorSystemProvider - Starting application default Akka system: application
[info] p.c.s.NettyServer$ - Listening for HTTP on /0:0:0:0:0:0:0:0:9000
(Server started, use Ctrl+D to stop and go back to the console...)
[info] Compiling 13 Scala sources and 1 Java source to C:\Play\exp\ch6_implicits\target\scala-2.11\classes...
[error] C:\Play\exp\ch6_implicits\conf\routes:6: type Application is not a member of package controllers
[error] GET / controllers.Application.index
[error] C:\Play\exp\ch6_implicits\conf\routes:7: type Shop is not a member of package controllers
[error] GET /catalog controllers.Shop.catalog
[error] C:\Play\exp\ch6_implicits\conf\routes:6: type Application is not a member of package controllers
[error] GET / controllers.Application.index
[error] C:\Play\exp\ch6_implicits\conf\routes:7: type Shop is not a member of package controllers
[error] GET /catalog controllers.Shop.catalog
[error] C:\Play\exp\ch6_implicits\conf\routes:6: type Application is not a member of package controllers
[error] GET / controllers.Application.index
[error] C:\Play\exp\ch6_implicits\conf\routes:7: type Shop is not a member of package controllers
[error] GET /catalog controllers.Shop.catalog
[error] 6 errors found
[error] (compile:compileIncremental) Compilation failed
[error] application -
! #6mafk6inc - Internal server error, for (GET) [/products/new] ->
play.sbt.PlayExceptions$CompilationException: Compilation error[type Application is not a member of package controllers]
at play.sbt.PlayExceptions$CompilationException$.apply(PlayExceptions.scala:27) ~[na:na]
at play.sbt.PlayExceptions$CompilationException$.apply(PlayExceptions.scala:27) ~[na:na]
at scala.Option.map(Option.scala:145) ~[scala-library-2.11.6.jar:na]
at play.sbt.run.PlayReload$$anonfun$taskFailureHandler$1.apply(PlayReload.scala:49) ~[na:na]
at play.sbt.run.PlayReload$$anonfun$taskFailureHandler$1.apply(PlayReload.scala:44) ~[na:na]
at scala.Option.map(Option.scala:145) ~[scala-library-2.11.6.jar:na]
at play.sbt.run.PlayReload$.taskFailureHandler(PlayReload.scala:44) ~[na:na]
at play.sbt.run.PlayReload$.compileFailure(PlayReload.scala:40) ~[na:na]
at play.sbt.run.PlayReload$$anonfun$compile$1.apply(PlayReload.scala:17) ~[na:na]
at play.sbt.run.PlayReload$$anonfun$compile$1.apply(PlayReload.scala:17) ~[na:na]
Application.scala is:
package controllers
import play.api._
import play.api.mvc._
// We extend the 'WithCart' trait, so we have an implicit conversion from RequestHeader to Cart
object Application extends Controller with WithCart {
def index = Action { implicit request =>
// The index template takes an implicit Cart, which is not available.
// However, the WithCart trait has an implicit conversion from
// RequestHeader to Cart, and we do have an implicit RequestHeader
// here, because `request` is a Request, which extends RequestHeader.
Ok(views.html.index())
}
def contact = Action { implicit request =>
Ok(views.html.contact())
}
}
Shop.scala is
package controllers
import play.api._
import play.api.mvc._
import models._
object Shop extends Controller with WithCart {
def catalog() = Action { implicit request =>
val products = ProductDAO.list
Ok(views.html.products.catalog(products))
}
}
And routes file is:
# Routes
# This file defines all application routes (Higher priority routes first)
# ~~~~
# Home page
GET / controllers.Application.index
GET /catalog controllers.Shop.catalog
GET /contact controllers.Application.contact
# Map static resources from the /public folder to the /assets URL path
GET /assets/*file controllers.Assets.at(path="/public", file)
Play Framework is 2.4.0 and about says:
[ch6_implicits] $ about
[info] This is sbt 0.13.8
[info] The current project is {file:/C:/Play/exp/ch6_implicits/}root 1.0-SNAPSHOT
[info] The current project is built against Scala 2.11.6
[info] Available Plugins: sbt.plugins.IvyPlugin, sbt.plugins.JvmPlugin, sbt.plugins.CorePlugin, sbt.plugins.JUnitXmlReportPlugin, play.sbt.Play, play.sbt.PlayAkkaHttpServer, play.sbt.PlayJava, play.sb
t.PlayLayoutPlugin, play.sbt.PlayNettyServer, play.sbt.PlayScala, play.sbt.routes.RoutesCompiler, play.twirl.sbt.SbtTwirl, com.typesafe.sbt.SbtNativePackager, com.typesafe.sbt.packager.archetypes.Akka
AppPackaging, com.typesafe.sbt.packager.archetypes.JavaAppPackaging, com.typesafe.sbt.packager.archetypes.JavaServerAppPackaging, com.typesafe.sbt.packager.archetypes.jar.ClasspathJarPlugin, com.types
afe.sbt.packager.archetypes.jar.LauncherJarPlugin, com.typesafe.sbt.packager.debian.DebianDeployPlugin, com.typesafe.sbt.packager.debian.DebianPlugin, com.typesafe.sbt.packager.debian.JDebPackaging, c
om.typesafe.sbt.packager.docker.DockerPlugin, com.typesafe.sbt.packager.jdkpackager.JDKPackagerDeployPlugin, com.typesafe.sbt.packager.jdkpackager.JDKPackagerPlugin, com.typesafe.sbt.packager.linux.Li
nuxPlugin, com.typesafe.sbt.packager.rpm.RpmDeployPlugin, com.typesafe.sbt.packager.rpm.RpmPlugin, com.typesafe.sbt.packager.universal.UniversalDeployPlugin, com.typesafe.sbt.packager.universal.Univer
salPlugin, com.typesafe.sbt.packager.windows.WindowsDeployPlugin, com.typesafe.sbt.packager.windows.WindowsPlugin, com.typesafe.sbt.web.SbtWeb, com.typesafe.sbt.jse.SbtJsEngine, com.typesafe.sbt.jse.S
btJsTask, com.typesafe.sbt.coffeescript.SbtCoffeeScript, com.typesafe.sbt.less.SbtLess, com.typesafe.sbt.jshint.SbtJSHint, com.typesafe.sbt.rjs.SbtRjs, com.typesafe.sbt.digest.SbtDigest, com.typesafe.
sbt.mocha.SbtMocha, com.typesafe.sbteclipse.plugin.EclipsePlugin
[info] sbt, sbt plugins, and build definitions are using Scala 2.10.4
[ch6_implicits] $
And Java version is:
C:\Play\exp\ch6_implicits>java -version
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
C:\Play\exp\ch6_implicits>javac -version
javac 1.8.0_45
Any ideas what's the problem and how to fix this?
So far other examples have compiled and run without error in my environment.
Thank you for your support!
Play 2.4, by default, generates a dependency injected router, unlike previously, when it used a static router. You have two options, remove the routesGenerator line from build.sbt so play will generate a static router, or (better) make your controllers classes instead of objects, and use dependency injection.
remove routesGenerator := InjectedRoutesGenerator from yout file build.sbt and all will work
Change your object to a class like this:
object Shop extends Controller with WithCart {
class Shop extends Controller with WithCart {
object Application extends Controller with WithCart {
class Application extends Controller with WithCart {
Include below code into into your conf/application.conf file:
play.allowGlobalApplication = true