Search code examples
androidjodatimeandroid-jodatime

Why does calling DateTime.withTime() from another method cause an exceptionInInitializerError


This code worked until just a couple days ago. Now it no longer works on android version 6.0. It does work on version 7.0 and newer.

public void setToDate(String quickDate) {
    DateTime toDate = new DateTime();

    if (quickDate.equals(context.getString(R.string.quickDate_today))) {
        fromDate = fromDate.withTimeAtStartOfDay();
        toDate = DateUtils.endOfDay(toDate);
    }
    ....        
}


 /**
 * @return a copy of dateTime with the time set to 11:59:59.999 pm.
 */
public static DateTime endOfDay(DateTime dateTime) {
    return dateTime.withTime(23, 59, 59, 999);
}

Here is the weird thing, If I move the withTime() call to be called directly instead of in a utility method like so:

public void setToDate(String quickDate) {
    DateTime toDate = new DateTime();

    if (quickDate.equals(context.getString(R.string.quickDate_today))) {
        fromDate = fromDate.withTimeAtStartOfDay();
        toDate = toDate.withTime(23, 59, 59, 999);
    }
    ....        
}

Then the code works, no exceptions thrown. Why? how can i make it work inside the utility method again?

Stack Trace:

Process: com.salesrabbit.android.sales.universal, PID: 29358
java.lang.ExceptionInInitializerError
    at com.salesrabbit.android.sales.universal.canvass.filter.filters.Filter.setQuickFromAndToDates(Filter.java:273)
    at com.salesrabbit.android.widget.FilterView.lambda$loadQuickDateMenu$3$FilterView(FilterView.java:203)
    at com.salesrabbit.android.widget.FilterView$$Lambda$3.onMenuItemClick(Unknown Source)
    at android.support.v7.widget.PopupMenu$1.onMenuItemSelected(PopupMenu.java:108)
    at android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:822)
    at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:171)
    at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:973)
    at android.support.v7.view.menu.MenuPopup.onItemClick(MenuPopup.java:127)
    at android.widget.AdapterView.performItemClick(AdapterView.java:310)
    at android.widget.AbsListView.performItemClick(AbsListView.java:1145)
    at android.widget.AbsListView$PerformClick.run(AbsListView.java:3066)
    at android.widget.AbsListView$3.run(AbsListView.java:3903)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:5417)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
 Caused by: java.lang.IllegalArgumentException: Unknown pattern character 'X'
    at java.text.SimpleDateFormat.validatePatternCharacter(SimpleDateFormat.java:323)
    at java.text.SimpleDateFormat.validatePattern(SimpleDateFormat.java:312)
    at java.text.SimpleDateFormat.<init>(SimpleDateFormat.java:365)
    at java.text.SimpleDateFormat.<init>(SimpleDateFormat.java:258)
    at com.salesrabbit.android.util.DateUtils.<clinit>(DateUtils.java:31)

Solution

  • As you probably know - ExceptionInInitializerError is thrown when Java fails to create an instance of a class - it usually indicates an error in the constructor but can also be from a static block in the class.

    Example (This class cannot be created because of the static block, you would see the error):

    class MyClass {
    
        private static boolean canDivideByZero;
        private Object unassignedValue;
    
        static {
             //Of course this code is ridiculous, it's just an example
             canDivideByZero = (10/0 == 10);
        }
    
        public MyClass() {
            //The stupid NPE here would also manifest as an ExceptionInInitializerError 
            if ( unassignedValue.equals("") ) {
                ...
            }
        }
    
    }
    

    Although you have not included the required stack trace your comment gives us a clue

    Here is the weird thing, If I move the withTime() ... Then the code works, no exceptions thrown

    So the issue can either be that your utility class is not instantiable or, something in the method you are calling is broken - and you are calling it from a constructor. Do bear in mind, that a utility class should really be final with a private constructor which does nothing.


    NOTE: In OP's specific example a static variable trying to use a value from another SDK was the cause. This is something I did not cover in my example above - static blocks and static variables are both initialized when the class is loaded and either can throw this exception.