Alex Rivera | Logout

Force initialization of Scala singleton object

Asked 2011-06-06T08:46:53.060
14

I'm working on an automatic mapping framework built on top of Dozer. I won't go into specifics as it's not relevant to the question but in general it's supposed to allow easy transformation from class A to class B. I'd like to register the projections from a class's companion object.

Below is a (simplified) example of how I want this to work, and a Specs test that assures that the projection is being registered properly.

Unfortunately, this doesn't work. From what I can gather, this is because nothing initializes the A companion object. And indeed, if I call any method on the A object (like the commented-out hashCode call, the projection is being registered correctly.

My question is - how can I cause the A object to be initialized automatically, as soon as the JVM starts? I don't mind extending a Trait or something, if necessary.

Thanks.

class A {
  var data: String = _
}

class B {
  var data: String = _
}

object A {
  projekt[A].to[B]

}

"dozer projektor" should {
  "transform a simple bean" in {
//    A.hashCode
      val a = new A
      a.data = "text"
      val b = a.-->[B]

      b.data must_== a.data
  }
}
Edit
Report

2 Answers

13

Short answer: You can't. Scala objects are lazy, and are not initialized until first reference. You could reference the object, but then you need a way of ensuring the executing code gets executed, reducing the problem back to the original problem.

answered 2011-06-06T09:02:03.593
4

In ended up doing this:

trait ProjektionAware with DelayedInit
{
  private val initCode = new ListBuffer[() => Unit]

  override def delayedInit(body: => Unit)
  {
    initCode += (() => body)
  }


  def registerProjektions()
  {
    for (proc <- initCode) proc()
  }
}

object A extends ProjektionAware {
  projekt[A].to[B]

}

Now I can use a classpath scanning library to initialize all instances of ProjektionAware on application bootstrap. Not ideal, but works for me.

answered 2011-06-09T14:46:09.627

Your Answer