yalkris yalkris - 7 months ago 7
Java Question

Initializing with @BeforeClass vs eager intialization in java

I am using spring with dependency injection and came across this puzzling piece of code in my TestNG class and want to clear my head around this issue

I have this below code

public class myBase {

@Autowired @Lazy @Qualifier("someInstanceA")
protected SomeClass someInstanceA;
.
.
}

public class myTestB extends myBase {
private String varB = someInstanceA.getVarB();

@Test
.
.
}


This above code gave me a NullPointerException at line

private String varB = someInstanceA.getVarB();


But when I do this below

public class myTestB extends myBase {
private String varB;

@BeforeClass
private void getVarB() {
varB = someInstanceA.getVarB();
}

@Test
.
.
}


The tests ran fine. I read that BeforeClass is like a default constructor and eager initialization is similar to initializing a variable using a default constructor. What am I missing here?

Answer

Short answer : Bean injection happens after creation of instances of your class.

Since in the creation of myTestB (which should start with an uppercase, by the way), you call getVarB on someInstanceA which is not yet injected, you get a NullPointerException.

The second case works because @BeforeClass run one time before first test run, after object creation. Thus when calling someInstanceA#getVarB in getVarB method, someInstanceA is already autowired and not null.