Why does adding a proxy trait work and direct inheritance fail?
I've created a runnable project over on github
if you clone the repo and run sbt console
followed by com.stackoverflow.question.main.Question.main(Array.empty[String])
, you should end up with the output:
this-is-the-host-name
java.lang.NullPointerException
at net.ceedubs.ficus.FicusConfig$class.as(FicusConfig.scala:9)
at net.ceedubs.ficus.SimpleFicusConfig.as(FicusConfig.scala:16)
at com.stackoverflow.question.AppConfig$class.conn(Config.scala:12)
at com.stackoverflow.question.main.BadDatabaseService$.conn(package.scala:12)
at com.stackoverflow.module.HostConnector$class.getHost(Database.scala:25)
at com.stackoverflow.question.main.BadDatabaseService$.getHost(package.scala:12)
at com.stackoverflow.module.DatabaseConnector$class.$init$(Database.scala:18)
at com.stackoverflow.question.main.BadDatabaseService$.<init>(package.scala:12)
at com.stackoverflow.question.main.BadDatabaseService$.<clinit>(package.scala)
at com.stackoverflow.question.main.Question$.main(App.scala:8)
... 43 elided
the first line this-is-the-host-name
is generated from the package object DatabaseService
while the NullPointerException
is generated by the BadDatabaseService
package object. Both are identical except that the DatabaseService
inherits from a proxy trait, while BadDatabaseService
inherits directly from the trait. The relevant code is here for convenience and can also be seen in the github repo.
package.scala:
package com.stackoverflow.question
import com.stackoverflow.module._
import com.stackoverflow.question.AppConfig
package main {
trait DataConfig extends ModuleConfig {
def conn = AppConfig.conn
}
object DatabaseService extends TableFunctions with HostConnector with DataConfig // This works with the proxy
object BadDatabaseService extends TableFunctions with HostConnector with AppConfig // This fails with NullPointerException, it's the ConfigFactory.load that returns null
}
Config.scala:
package com.stackoverflow.question
import com.stackoverflow.module.{ ModuleConfig, ModuleConfiguration }
import com.typesafe.config.{ Config, ConfigFactory }
import net.ceedubs.ficus.Ficus._
object AppConfig extends AppConfig
trait AppConfig extends ModuleConfig {
def config: Config = ConfigFactory.load()
def conn = config.as[ModuleConfiguration]("stackoverflow.conn")
val name = config.as[String]("stackoverflow.name")
}
Please help me understand why I can't inherit directly from AppConfig
and why ConfigFactory.load
returns null when AppConfig
is inherited but not when it's co-object is called via proxy in inherited through that.