Android issue sending events from Java to Lua

I’ve been playing around with the trial version of CoronaCards for Android.  It’s very impressive.  I’m planning to use it for a real project, but I’ve run into a strange issue when sending events from Java to Lua.  The crash I’m getting results in:

10-16 19:38:11.214: W/System.err(21339): java.lang.NullPointerException

10-16 19:38:11.214: W/System.err(21339): at com.ansca.corona.CoronaLua.pushHashtable(CoronaLua.java:271)

10-16 19:38:11.214: W/System.err(21339): at com.ansca.corona.CoronaView.sendEvent(CoronaView.java:190)

Because I cannot see the source code of CoronaLua.pushHashtable, I cannot see what is causing the NullPointerException.  Can one of the devs help here please?  I can’t figure out how to fix it because I don’t even know where to begin looking without knowing what is null.

Here is my Java code that causes it:

Hashtable<Object, Object> ht = new Hashtable<Object, Object>();

ht.put(“name”, “appsUpdated”);

mSendingView.sendEvent(ht);

And strangely, if I comment out the ht.put(), and send an empty Hashtable, the NullPointerException doesn’t happen.  But of course, an empty hashtable is not useful.

One more clue - a few times, the crash didn’t occur even when sending real data, so it seems like possibly some sort of race condition in the CoronaCards Android code.

Do you have a sample project which displays the issue?

Well, my android project is really big, so if you really need me to, I can try to reproduce this problem in a small, sample project.  But I don’t know for sure that I can, since the problem seems sporadic.

In the meantime, can you let me at least know what is null in CoronaLua.java line 271?  That will at least give me a clue.  I’m usually quite good at debugging, but because the crash is happening in Corona’s code, I am left doing wild-guess trial & error debugging, which is very frustrating and time-consuming. Given how sometimes it works but usually it crashes, leads me to think it’s a race condition in the Corona code.

The null pointer should be referencing the Lua State object or the hashtable.  You don’t pass that in, we get it ourselves and we can’t reproduce it which is why we’re hoping you can give us a sample project.  

The exact code snippet is here:

if (hashtable == null) {

    L.newTable();

    return;

}

L.newTable(0, hashtable.size()); // This is line 271

As you can see if the hashtable is null we return before hand BUT we also use a the LuaState object in that case as well so I’m not sure what the issue is.

I will try to put together a sample project that crashes, but in the meantime, here is more information that might help you figure out what’s going on in the Corona code.

Right now, I’m calling sendEvent() from the onResume() method of the Activity that has my CoronaView as it’s main content view.  It crashes.  I’ve tried moving it to onPostResume() and it crashes there too.  However, if I call sendEvent() from a user-initiated method of the Activity, like onOptionsItemSelected(), it doesn’t crash.

Does that help?

So, based on what you said about the LuaState object being null, I did lots of experimentation based on what I know about Android threads.

The good news is that I was able to prevent the NullPointerException by forcing the call to sendEvent() to run on the UI thread. As in:

final Hashtable<Object, Object> fht = ht;

myActivity.runOnUiThread(new Runnable() {

  public void run() {

    mSendingView.sendEvent(fht);

  }

});

I don’t know why this works, but so far I haven’t had the NullPointerException occur when doing it this way, even when doing this from onResume(), whereas before running it on the current thread crashed almost every time.

However, the bad news is that sometimes, and it seems random, it will crash like this instead: 

10-17 17:55:24.607: E/AndroidRuntime(8804): java.lang.IllegalArgumentException: illegal type

10-17 17:55:24.607: E/AndroidRuntime(8804):  at com.naef.jnlua.LuaState.lua_settable(Native Method)

10-17 17:55:24.607: E/AndroidRuntime(8804):  at com.naef.jnlua.LuaState.setTable(Unknown Source)

10-17 17:55:24.607: E/AndroidRuntime(8804):  at com.ansca.corona.CoronaLua.pushHashtable(CoronaLua.java:279)

10-17 17:55:24.607: E/AndroidRuntime(8804):  at com.ansca.corona.CoronaView.sendEvent(CoronaView.java:190)

So two questions:

  1. Based on your internal knowledge of the Android CoronaCards code, can you tell why forcing the call to sendEvent() to be on the UI thread fixes the LuaState null pointer issue?  And do you think you should change the Android CoronaCards code so that the crash never happens, regardless of the thread?
  2. Any ideas what is causing the 2nd, seemingly random crash? I wonder if it’s related to threads too.

I’m still actively doing experimentation, both on the Android emulator and on real devices, and will let you know anything I find.

I found another intermittent problem when calling sendEvent(). About 5% of the time, this happens:

10-18 05:26:18.994: A/libc(1421): Fatal signal 11 (SIGSEGV) at 0xb1d84dbc (code=2), thread 1421

I’m really hoping that it’s related to the other issues I reported and that Corona can fix them all at once.

dchan,

I have a simple sample project that reproduces the NullPointerException at CoronaLua.java line 271. I will send it to you now.

Hi,

The issue seems to be that the lua state object isn’t created yet when you’re trying to send the event.  Please try doing the following:

@Override

public void onResume() {

super.onResume();

Log.v(“test”, this.getLocalClassName() + “.onResume()”);

        mMainView.resume();

        CoronaEnvironment.addRuntimeListener(new CoronaRuntimeListener() {

            @Override

            public void onLoaded(CoronaRuntime coronaRuntime) {

            }

            @Override

            public void onStarted(CoronaRuntime coronaRuntime) {

                Hashtable<Object, Object> ht = new Hashtable<Object, Object>();

                ht.put(“name”, “testEvent”);

                ht.put(“message”, “Hello Corona! Sent from onResume().”);

//

//                // This way results in NullPointerException at CoronaLua.java:271

                mMainView.sendEvent(ht);

            }

            @Override

            public void onSuspended(CoronaRuntime coronaRuntime) {

            }

            @Override

            public void onResumed(CoronaRuntime coronaRuntime) {

            }

            @Override

            public void onExiting(CoronaRuntime coronaRuntime) {

            }

        });

// Create event for sending to Corona/Lua

}

You can read more about the listener here: http://docs.coronalabs.com/daily/native/android/html/com/ansca/corona/CoronaRuntimeListener.html

This way you’re waiting until Corona is fully set up before trying to send any events.

Thanks Danny.

Waiting for the CoronaRuntimeListener.onStarted() to fire before calling sendEvent() does seem to fix the NullPointerException. May I suggest that the CoronaCards sendEvent() code check for the null and return a result code to the caller, rather than crash?

However, even after waiting for Corona to be fully setup before calling sendEvent, I’m still running into problems:

  1. When I call sendEvent() from an AsyncTask, the sendEvent() results in a crash with:

10-20 22:02:10.446: A/libc(4749): Fatal signal 11 (SIGSEGV) at 0x000000f5 (code=1), thread 4879 (AsyncTask #4)

I am able to fix this partially with the runOnUiThread() trick, and it cuts down the crashes a lot, but it still happens sometimes.

  1. In both the modified sample project and the fishies sample project, if I rotate my device, sometimes the rotation works, but usually the app crashes.  When it crashes, sometimes I get this, but not always (seems random):

10-20 21:42:27.256: A/libc(507): Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1), thread 507 (example.fishies)

or 

10-20 21:52:56.646: A/libc(3586): bionic/libstdc++/src/pure_virtual.cpp:6: void __cxa_pure_virtual(): assertion “!“Pure virtual function called. Are you calling virtual methods from a destructor?”” failed

10-20 21:52:56.646: A/libc(3586): Fatal signal 6 (SIGABRT) at 0x00000e02 (code=-6), thread 3586 (om.example.test)

  1. I’ve gotten this crash a few times when I call CoronaView.destroy() from my activity’s onDestroy() function:

10-20 21:40:07.046: E/AndroidRuntime(32232): Caused by: java.util.ConcurrentModificationException

10-20 21:40:07.046: E/AndroidRuntime(32232): at java.util.AbstractList$SimpleListIterator.next(AbstractList.java:62)

10-20 21:40:07.046: E/AndroidRuntime(32232): at network.NetworkRequest.abortOpenConnections(NetworkRequest.java:49)

10-20 21:40:07.046: E/AndroidRuntime(32232): at network.LuaLoader.onExiting(LuaLoader.java:149)

10-20 21:40:07.046: E/AndroidRuntime(32232): at com.ansca.corona.CoronaEnvironment$RuntimeEventHandler.onExiting(CoronaEnvironment.java:470)

10-20 21:40:07.046: E/AndroidRuntime(32232): at com.ansca.corona.CoronaRuntime.onExiting(CoronaRuntime.java:422)

10-20 21:40:07.046: E/AndroidRuntime(32232): at com.ansca.corona.CoronaRuntime.dispose(CoronaRuntime.java:76)

10-20 21:40:07.046: E/AndroidRuntime(32232): at com.ansca.corona.CoronaView.destroy(CoronaView.java:169)

Bottom line is that while the CoronaRuntimeListener.onStarted() tip and the runOnUiThread() trick are helping, my apps are still very unstable.

Here are some sample stack traces of crashes that I’m still getting on sendEvent().

10-21 00:53:43.548: E/AndroidRuntime(9415): FATAL EXCEPTION: main

10-21 00:53:43.548: E/AndroidRuntime(9415): Process: com.easy_launcher, PID: 9415

10-21 00:53:43.548: E/AndroidRuntime(9415): com.naef.jnlua.LuaRuntimeException: invalid replacement value (a table)

10-21 00:53:43.548: E/AndroidRuntime(9415): at com.naef.jnlua.LuaState.lua_pcall(Native Method)

10-21 00:53:43.548: E/AndroidRuntime(9415): at com.naef.jnlua.LuaState.call(Unknown Source)

10-21 00:53:43.548: E/AndroidRuntime(9415): at com.ansca.corona.CoronaLua.dispatchRuntimeEvent(CoronaLua.java:293)

10-21 00:53:43.548: E/AndroidRuntime(9415): at com.ansca.corona.CoronaView.sendEvent(CoronaView.java:191)

10-21 00:57:36.598: E/AndroidRuntime(10526): FATAL EXCEPTION: main

10-21 00:57:36.598: E/AndroidRuntime(10526): Process: com.easy_launcher, PID: 10526

10-21 00:57:36.598: E/AndroidRuntime(10526): java.lang.IllegalArgumentException: illegal type

10-21 00:57:36.598: E/AndroidRuntime(10526): at com.naef.jnlua.LuaState.lua_settable(Native Method)

10-21 00:57:36.598: E/AndroidRuntime(10526): at com.naef.jnlua.LuaState.setTable(Unknown Source)

10-21 00:57:36.598: E/AndroidRuntime(10526): at com.ansca.corona.CoronaLua.pushHashtable(CoronaLua.java:279)

10-21 00:57:36.598: E/AndroidRuntime(10526): at com.ansca.corona.CoronaView.sendEvent(CoronaView.java:190)

10-21 00:59:54.638: E/AndroidRuntime(11665): FATAL EXCEPTION: main

10-21 00:59:54.638: E/AndroidRuntime(11665): Process: com.easy_launcher, PID: 11665

10-21 00:59:54.638: E/AndroidRuntime(11665): java.lang.IllegalArgumentException: illegal index

10-21 00:59:54.638: E/AndroidRuntime(11665): at com.naef.jnlua.LuaState.lua_settable(Native Method)

10-21 00:59:54.638: E/AndroidRuntime(11665): at com.naef.jnlua.LuaState.setTable(Unknown Source)

10-21 00:59:54.638: E/AndroidRuntime(11665): at com.ansca.corona.CoronaLua.pushHashtable(CoronaLua.java:279)

10-21 00:59:54.638: E/AndroidRuntime(11665): at com.ansca.corona.CoronaView.sendEvent(CoronaView.java:190)

Hi,

I’ve purchased the license this week and since then I’ve been experiencing the same problems. 

While the Corona code runs perfectly on the simulator, it crashes when I try to send events from Java that are triggered every 1 sec.

The exceptions and stack trace seem very random, and I think this might be a problem with Corona’s latest build. 

Please help us!

Hey folks,

I believe the issues mentioned here should be fixed in the next build.  One thing to note is that we had to make 1 breaking change.  Previously when you called coronaView.sendEvent(hashTable) it would immediately return the value returned from Lua.  Now if you want to get the value returned from Lua you’ll have to pass in a listener so it would look like coronaView.sendEvent(hashTable, listener).  If you previously didn’t care about the return value then nothing will change.  Please let me know if you have any other issues, thanks.

Thanks Danny. When the new build is ready, I will try it out and let you know how it goes.

Just tried the new build. So far so good. Haven’t tested the event sending extensively, but so far no crashes.

Do you have a sample project which displays the issue?

Well, my android project is really big, so if you really need me to, I can try to reproduce this problem in a small, sample project.  But I don’t know for sure that I can, since the problem seems sporadic.

In the meantime, can you let me at least know what is null in CoronaLua.java line 271?  That will at least give me a clue.  I’m usually quite good at debugging, but because the crash is happening in Corona’s code, I am left doing wild-guess trial & error debugging, which is very frustrating and time-consuming. Given how sometimes it works but usually it crashes, leads me to think it’s a race condition in the Corona code.

The null pointer should be referencing the Lua State object or the hashtable.  You don’t pass that in, we get it ourselves and we can’t reproduce it which is why we’re hoping you can give us a sample project.  

The exact code snippet is here:

if (hashtable == null) {

    L.newTable();

    return;

}

L.newTable(0, hashtable.size()); // This is line 271

As you can see if the hashtable is null we return before hand BUT we also use a the LuaState object in that case as well so I’m not sure what the issue is.

I will try to put together a sample project that crashes, but in the meantime, here is more information that might help you figure out what’s going on in the Corona code.

Right now, I’m calling sendEvent() from the onResume() method of the Activity that has my CoronaView as it’s main content view.  It crashes.  I’ve tried moving it to onPostResume() and it crashes there too.  However, if I call sendEvent() from a user-initiated method of the Activity, like onOptionsItemSelected(), it doesn’t crash.

Does that help?

So, based on what you said about the LuaState object being null, I did lots of experimentation based on what I know about Android threads.

The good news is that I was able to prevent the NullPointerException by forcing the call to sendEvent() to run on the UI thread. As in:

final Hashtable<Object, Object> fht = ht;

myActivity.runOnUiThread(new Runnable() {

  public void run() {

    mSendingView.sendEvent(fht);

  }

});

I don’t know why this works, but so far I haven’t had the NullPointerException occur when doing it this way, even when doing this from onResume(), whereas before running it on the current thread crashed almost every time.

However, the bad news is that sometimes, and it seems random, it will crash like this instead: 

10-17 17:55:24.607: E/AndroidRuntime(8804): java.lang.IllegalArgumentException: illegal type

10-17 17:55:24.607: E/AndroidRuntime(8804):  at com.naef.jnlua.LuaState.lua_settable(Native Method)

10-17 17:55:24.607: E/AndroidRuntime(8804):  at com.naef.jnlua.LuaState.setTable(Unknown Source)

10-17 17:55:24.607: E/AndroidRuntime(8804):  at com.ansca.corona.CoronaLua.pushHashtable(CoronaLua.java:279)

10-17 17:55:24.607: E/AndroidRuntime(8804):  at com.ansca.corona.CoronaView.sendEvent(CoronaView.java:190)

So two questions:

  1. Based on your internal knowledge of the Android CoronaCards code, can you tell why forcing the call to sendEvent() to be on the UI thread fixes the LuaState null pointer issue?  And do you think you should change the Android CoronaCards code so that the crash never happens, regardless of the thread?
  2. Any ideas what is causing the 2nd, seemingly random crash? I wonder if it’s related to threads too.

I’m still actively doing experimentation, both on the Android emulator and on real devices, and will let you know anything I find.