Fabrizio Fortino
Fabrizio Fortino

Reputation: 1606

groovy: @Lazy annotation does not work in trait

I am trying to use the @Lazy annotation (http://docs.groovy-lang.org/docs/next/html/documentation/#xform-Lazy) in a trait to initialise an object only if used.

trait MyTrait{
  @Lazy String test = {
    new Exception().printStackTrace()
    return 'test'
  }()
}

The object is created regardless is used or not. I have added a printStackTrace in the initialisation closure to make sure I don't call the variable inadvertently. The object gets created when the class implementing the trait is instantiated.

Upvotes: 0

Views: 420

Answers (1)

pczeus
pczeus

Reputation: 7868

This appears to be a bug. The @Lazy does not work in trait's. You should create an issue ticket with Groovy for this to be corrected.

To prove the issue, I have extended your code to create a test (run as a simple groovy script) that shows that @Lazy works for a Class, but fails the assertion when used on a trait:

    class MyBase{
      @Lazy String test = { 'test' }()
    }
    class TestBaseClass extends MyBase{}
    def tb = new TestBaseClass();

    //Dump the current state to output an assert test hasn't been initialized
    println "Testing @Lazy on a Class.."
    println tb.dump()
    assert tb.dump().contains('test=null') //FOR A CLASS, THIS WILL SUCCEED

    //Access the test property causing initialization
    println "Accessing the test property."
    assert tb.test

    //Dump the current state to output an assert test has now been initialized
    println tb.dump()
    assert tb.test == 'test'

    trait MyTrait{
      @Lazy String test = { 'test' }()
    }
    class TestClass implements MyTrait{}
    def t = new TestClass();

    //Dump the current state to output an assert test hasn't been initialized
    println "\nTesting @Lazy on a Trait.."
    println t.dump()
    assert t.dump().contains('test=null') //FOR A TRAIT, THIS WILL FAIL THE ASSERTION - A BUG?

    //Access the test property causing initialization
    println "Accessing the test property."
    assert t.test

    //Dump the current state to output an assert test has now been initialized
    println t.dump()
    assert t.test == 'test'

Upvotes: 1

Related Questions