in `MemJogLib.kt`: ```object MemJogLib { var ...
# getting-started
g
in `MemJogLib.kt`:
Copy code
object MemJogLib {

    var testingOnlyChangeForTesting = false

    val BUILD_ROOT: String = File(".").canonicalPath

    private val MJL_BOOKS_DIR: String? = System.getenv("MJL_BOOKS_DIR")

    @JvmStatic
    fun getMjlBookDir(): String =
        if (testingOnlyChangeForTesting) {
            "$BUILD_ROOT/target/test-classes"
        } else {
            MJL_BOOKS_DIR!! // <= NullPointerException HERE
        }
At the start of all tests, I make sure I call initialized:
Copy code
private val initialized: Boolean by lazy {
        testingOnlyChangeForTesting = true
With
testingOnlyChangeForTesting = true
, the second branch of the
if
statement shouldn't even be called! When I run my tests from Maven at command line on my desktop, everything works perfectly. Using command-line Maven on the build server, I get:
Copy code
java.lang.ExceptionInInitializerError
	at com.goalqpc.memJogLib.TestGlobals$initialized$2.invoke(TestGlobals.kt:145)
	at com.goalqpc.memJogLib.TestGlobals$initialized$2.invoke(TestGlobals.kt:144)
	at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
	at com.goalqpc.memJogLib.TestGlobals.getInitialized(TestGlobals.kt:144)
	at com.goalqpc.memJogLib.TestGlobals.testDbInMemory(TestGlobals.kt:220)
	at com.goalqpc.memJogLib.servlet.MjlServletHandlerTest.before(MjlServletHandlerTest.kt:44)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.RunBefores.invokeMethod(RunBefores.java:33)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:242)
	at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:137)
	at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
	at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
	at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
	at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)

Caused by: java.lang.NullPointerException
	at com.goalqpc.memJogLib.MemJogLib.getMjlBookDir(MemJogLib.kt:66)
	at com.goalqpc.memJogLib.MemJogLib.<clinit>(MemJogLib.kt:72)
	... 39 more
i
object class is like static java class
g
I thought a Kotlin Object has an
INSTANCE
that gets created by a private constructor - a Singleton pattern? Are you suggesting that the
@JvmStatic
and
@JvmField
annotations are messing with the initialization code somehow? It might be weird to use them on a Kotlin Object?
i
From the call stack it seems that you call
getMjlBookDir
from the class initializer, that is before
initialized
gets chance to be executed.
✔️ 1