Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala :: lazy value is null unless printed?

Given the trait (simplified)

trait A {
  val eventStream: EventStream
  val credentialsStorage = // something here
  val userStorage = // something here
  val crypto = // something here
  ...    
  lazy val authSvc = new CoreAuthentication(credentialsStorage, new AuthenticationProviderResolver, userStorage, eventStream, crypto)
}

class T extends A with TraitProvidingEventStream with FlatSpec with [lot of another traits here] {

  val eventStream = systemFromTraitProvidingEventStream.eventStream

  "This" should "work" in {
    println(authSvc) // this is "magic"
    val user = authSvc.doSomethingWithUser(...);
  }
}

if I remove line marked as //this is "magic", then I will get NullPointerException on the next line, so authSvc is null.

What may be wrong there?

I wasn't be able to create clean small test case for that, usually this works well

like image 472
jdevelop Avatar asked Nov 24 '12 14:11

jdevelop


1 Answers

This came up once on the ML: If an exception is thrown when initializing a lazy val, the val is null; but you can attempt to init again and it can work magically. (That is, the "initialized" bit flag for the lazy val is not set on the first failed attempt to initialize.)

I think the case on the ML had to do with init order of vals in traits, so maybe that's your problem. It's infamously dangerous to rely on it, hence the advice to use defs in traits. See Luigi's comment on DelayedInit.

like image 64
som-snytt Avatar answered Sep 28 '22 08:09

som-snytt