2
votes

Today I tried to investigate this issue: https://github.com/codenameone/CodenameOne/issues/2975 I'm writing here to ask how I can find exactly what goes wrong. This bug is frustrating.

Basically, on iOS only, I have this error, that happens after some random app usage:

java.lang.NullPointerException
    at com_codename1_ui_Form.pointerReleased:3758
    at net_informaticalibera_cn1_simpleapi_OuterForm.pointerReleased:360
    at com_codename1_ui_Component.pointerReleased:4679
    at com_codename1_ui_Display.handleEvent:2289
    at com_codename1_ui_Display.edtLoopImpl:1214
    at com_codename1_ui_Display.mainEDTLoop:1132
    at com_codename1_ui_RunnableWrapper.run:120
    at com_codename1_impl_CodenameOneThread.run:176
    at java_lang_Thread.runImpl:153

I've overridden the pointerReleased method to see if x and y are acceptable values when the previous exception is thrown, it seems so:

@Override
    public void pointerReleased(int x, int y) {
        try {
            super.pointerReleased(x, y);
        } catch (Exception ex) {
            Log.p("OuterForm.pointerReleased ERROR, x->" + x + ", y->" + y + ", https://github.com/codenameone/CodenameOne/issues/2975");
            Log.e(ex);
            SendLog.sendLogAsync();
        }
    }

Using that override, that is equivalent to the crash protection feature, after the first time that this exception happens the TextArea components are not more usable: the tap on them doesn't open the VKB.

In short, there is a NullPointerException inside the iOS port of Form.pointerReleased: how can I discover which line of that method throws the exception? I hope to find info that can help for the bug resolution.

1
I can run the app with Xcode, but I don’t know how to debug with issue - Francesco Galgani
If you run it in the xcode debugger it should break on the exception line and give you the full stack trace.in the native code. - Shai Almog
Hi Shai, unfortunately Xcode doesn't stop on the exception line, that's why I need a more elaborated suggestion about debugging this kind of issue. The native log produced by Xcode has the same stack trace that I reported here. - Francesco Galgani
I found a solution to solve this issue without the need of Xcode. I added an answer to my question. - Francesco Galgani

1 Answers

2
votes

The problem is that the code of the method public void pointerReleased(int x, int y) of the class Form is all inside a try... finally, that hides the actual cause of the exception. To get the actual cause, I used the following override in the BaseForm class of my app, that extends Form and that I use as superclass for all other Forms:

@Override
    public void pointerReleased(int x, int y) {
        try {
            Component cmp = instance.getResponderAt(x, y);
            if (cmp != null) {
                cmp.pointerReleased(x, y);
            }
        } catch (Exception ex) {
            Log.p("BaseForm.pointerReleased ERROR, x->" + x + ", y->" + y + ", https://github.com/codenameone/CodenameOne/issues/2975");
            Log.e(ex);
            SendLog.sendLogAsync();
        }
    }

As expected, this gave me the actual cause of the bug, that was inside a lambda expression of a TextArea actionListener: more specifically, the issue was a revalidate on an Container reference that can be null in some circumstances (oddly, this happens only on iOS). After that, I removed the previous override (that broke some functionalities), I fixed my code preventing the revalidate on a null object (with an if condition) and the bug disappeared (I've done a test with a long usage of the app).