Timer creation exception in Kernel project (java.lang.ExceptionInInitializerError)

Hello,

I’m working on a simple Kernel application, I get the following exception when starting the Kernel on my device:

Exception in thread "main" java.lang.ExceptionInInitializerError: java.lang.NullPointerException
     at java.lang.System.getStackTrace(Unknown Source)
     at java.lang.Throwable.fillInStackTrace(Throwable.java:82)
     at java.lang.Throwable.<init>(Throwable.java:51)
     at java.lang.Error.<init>(Error.java:26)
     at java.lang.LinkageError.<init>(LinkageError.java:26)
     at java.lang.ExceptionInInitializerError.<init>(ExceptionInInitializerError.java:22)
     at java.lang.Thread.clinitWrapper(Thread.java:490)
     at java.lang.Thread.callWrapper(Thread.java:449)
Caused by: java.lang.NullPointerException
     at com.is2t.tools.ArrayTools.add(ArrayTools.java:86)
     at ej.kf.Kernel.addFeatureStateListener(Kernel.java:383)
     at com.is2t.bon.timer.TimerTaskListKernel.<init>(TimerTaskListKernel.java:30)
     at com.is2t.bon.BONFactoryKF.newTimerTaskList(BONFactoryKF.java:32)
     at ej.bon.Timer.<init>(Timer.java:107)
     at ej.bon.Timer.<init>(Timer.java:87)
     at com.mycompany.helloworld.Main.<clinit>(Main.java:29)
     at java.lang.Thread.execClinit(Unknown Source)
     at java.lang.Thread.clinitWrapper(Thread.java:483)
     at java.lang.Thread.callWrapper(Thread.java:449)

Find below a snippet of my Kernel code with the faulty line:

Could you help me to figure out what is going on?

Regards,

Fabrice

Hello Fabrice,

According to the stack trace, I think this is an issue related to a wrong clinit order. It seems to happen here because SOAR is unable to detect (statically) that the Timer constructor depends on the Kernel clinit.

To fix your code, I see two options:

  • OPT1: move the creation of your application Timer out of clinit code, for example at the beginning of your main method. Usually this is a good practice to avoid too many code invoked from clinits.
  • OPT2: Keep your code as-is, and manually declare the right dependency order. Declare a file named app.clinitdesc in your src/main/resources folder with the following content (replace [your_main_class] by the fully qualified name of your class declaring the Timer):
    <clinit>
        <type name="[your_main_class]" depends="ej.kf.Kernel"/>
    </clinit>
    

PS: for more information about how clinits are processed, please refer to SOAR — MicroEJ Documentation

–Frédéric

Hello Frédéric,

Thanks for the help! It works fine with option 2).

Regards,

Fabrice