local iOS build with maven does not like WeakReferences - runtime error in iOS simulator

33 views
Skip to first unread message

P5music

unread,
May 3, 2021, 2:27:19 AM5/3/21
to CodenameOne Discussions

I compiled my app with maven and generated the iOS Xcode project.
When I run it into the iOS simulator (iPad 8th gen) I get this early error:
Thread 4: EXC_BAD_ACCESS (code=1, address=0x30)
at this instruction
return (*(struct obj__com_myapp_app_AppData*)__cn1T).com_myapp_app_AppData_appVersion;
Where only the .com_myapp_app_AppData_appVersion part is in red. The iOS build code is below.

It happens at
((AppData)appData.get()).appVersion
Inside AppJSONData class, that has a weak reference to the AppData instance.
That seems to be a CodenameOne internal problem, not of my app, because it does not happen either on the simulator, or on Android, or a real iOS device (32bit).
Am I right?
What’s happening. How can it be avoided? Should weak references be avoided? I think this one can be removed because it has the same app lifetime, but there are also others that are dynamic.
Also it can be something that is wrong in the CN1 maven system to be fixed.
Thanks in advance

#include "com_myapp_app_AppData.h"
#include "com_myapp_app_AppData.h"
#include "com_myapp_app_AppJSONData.h"
#include "java_io_IOException.h"
#include "java_lang_NullPointerException.h"
#include "java_lang_String.h"
#include "java_lang_ref_WeakReference.h"
const struct clazz *base_interfaces_for_com_myapp_app_AppData[] = {};
struct clazz class__com_myapp_app_AppData = {
  DEBUG_GC_INIT &class__java_lang_Class, 999999, 0, 0, 0, 0, &__FINALIZER_com_myapp_app_AppData ,0 , &__GC_MARK_com_myapp_app_AppData,  0, cn1_class_id_com_myapp_app_AppData, "com.myapp.app.AppData", 0, 0, 0, JAVA_FALSE, &class__java_lang_Object, base_interfaces_for_com_myapp_app_AppData, 0, 0, 0
, 0, 0, 0, 0, 0, 0};

JAVA_OBJECT get_field_com_myapp_app_AppData_appVersion(JAVA_OBJECT __cn1T) {
  return (*(struct obj__com_myapp_app_AppData*)__cn1T).com_myapp_app_AppData_appVersion;
}

Steve Hannah

unread,
May 3, 2021, 7:27:51 AM5/3/21
to codenameone...@googlegroups.com
When running with the debugger (in Xcode) it will stop on these error.  When running normally, it "catches" them and proceeds.

((AppData)appData.get()).appVersion

That doesn't look safe.  You say appData is a weak reference? Then get() may return null?  Then the .appVersion will be an NPE, which is essentially what you're seeing.

--
You received this message because you are subscribed to the Google Groups "CodenameOne Discussions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to codenameone-discu...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/codenameone-discussions/c0d25bdf-85a4-4253-ade1-fcaed6c484dbn%40googlegroups.com.


--
Steve Hannah
Software Developer
Codename One

P5music

unread,
May 3, 2021, 9:01:47 AM5/3/21
to CodenameOne Discussions
appVersion is just a string, appData is a weak reference but nothing is null, as I said the app works outside of the iOS simulator.
I think that it does not like weak references.
What could be the cause of the NPE? Maybe those pointers?
Maybe the weak reference is not created at all in the translated code (build bug)?
Regards

Steve Hannah

unread,
May 3, 2021, 9:13:47 AM5/3/21
to codenameone...@googlegroups.com
> appData is a weak reference but nothing is null

((AppData)appData.get()).appVersion

If appData is a weak reference, then appData.get() may be null.



P5music

unread,
May 3, 2021, 11:35:08 AM5/3/21
to CodenameOne Discussions
We are talking of Java, so the fact that some reference could be null is not already an error, indeed only if it is null at runtime there is NPE.
Unless something in the "compiled" XCode project does not like weak references (or things that can in theory be null) so it complains.
But this is at runtime, so it is complaining at runtime when that value is not null, at least not because of the app Java instructions, said that the same code with no modifications is perfectly running in the simulator and Android device and iOS real device.
I debugged in IntelliJ Idea and followed the pointers and they are not null. I knew it already, the instructions sequence is very simple, it is done on app startup and it is the same on every platform, no room for leaving any null pointer.

Otherwise I do not understand what you really mean. Please explain.
Regards

Steve Hannah

unread,
May 3, 2021, 11:58:17 AM5/3/21
to codenameone...@googlegroups.com
When running in the Xcode debugger, it always stops on these EXC_BAD_ACCESS signals.  When running on device (without Xcode debugger), it catches the signal and throws an NPE.

> I debugged in IntelliJ Idea and followed the pointers and they are not null

With a WeakReference you cannot count on the reference being maintained - it could be set to null at any time.  You need to check the value of the reference before using it, or you will get an NPE. 

Solution is simple:  Always check the values of weak references before using them to make sure they're not null.

P5music

unread,
May 3, 2021, 12:53:35 PM5/3/21
to CodenameOne Discussions
Ok I will check everything as soon as possible but let me say that:
no null pointer exception is raised when the app is run on the simulator or Android device or iOS real device.

So if you say
"When running on device (without Xcode debugger), it catches the signal and throws an NPE" I have to point out that no NPE is thrown.

And about
"With a WeakReference you cannot count on the reference being maintained - it could be set to null at any time.  You need to check the value of the reference before using it, or you will get an NPE. "
I ensure you that a few instruction are called and they are the same sequence on every platform at app startup, and there are no flow-diagram options going through a path or another.
So no null references can be there, unless they are something related to the WeakReference handling of the translated code.

Regards

Steve Hannah

unread,
May 3, 2021, 1:09:28 PM5/3/21
to codenameone...@googlegroups.com
> So no null references can be there, unless they are something related to the WeakReference handling of the translated code.

You are missing the point.  A WeakReference is not deterministic.  It can be cleared at any time by the VM.  You can debug and test on other devices all you like, and the absence of an NPE doesn't prove anything.  You *always* need to guard against null values in WeakReferences.

P5music

unread,
May 3, 2021, 3:21:15 PM5/3/21
to CodenameOne Discussions
I will check for sure what you say, but please note that

no object is being garbage-collected, there are strong references to AppData instance, and AppJSONData is strongly referenced by AppData instance itself: even if the latter has a weak reference to the former, they are stable in memory.
appData->AppData->AppJSONData(->)AppData

What you say seems to be a very unusual case, never happened to me. The app is just starting and very little or no memory at all is used.
Maybe I did not explain correctly the references involved, so maybe there is something wrong as I pointed out.

Regards
Reply all
Reply to author
Forward
0 new messages