[BUG] Non-existent imported module causes runtime error on Android

Hi all,

Firstly, let me apologise if I am posting this in the wrong place…

I have found a bug when an app is compiled for android (it may exist for iOS, I haven’t been able to check however).

Note this line: [lua]local util = require( “Util” )[/lua]

This was a module I wrote and imported for my project. It happened to actually be the incorrect filename, it should have been:

[lua]require(“util”)[/lua]

Note the lowercase ‘u’.  However, it was actually unused at this point, i.e. no functions from ‘util.lua’ were being called, so my guess is that the simulator simply ignored it and didn’t show an error

When the application was built for android it would not run and there was no error message on the test device. After looking for an error using logcat I found what was causing this (output below).

You will see that there is a runtime error when attempting to load a resource named ‘Util.lua’ which obviously doesn’t exist.

Now clearly if the simulator had warned me that there was no resource named ‘Util.lua’ before the build, I would have corrected it and this would have been avoided - there was no such warning however and no feedback on the test device itself.

Hope this all made sense.

Regards,

adarer

LOGCAT OUTPUT:

03-11 01:52:54.804: W/System.err(4876): java.lang.ClassNotFoundException: Util.LuaLoader

03-11 01:52:54.804: W/System.err(4876):     at java.lang.Class.classForName(Native Method)

03-11 01:52:54.804: W/System.err(4876):     at java.lang.Class.forName(Class.java:251)

03-11 01:52:54.804: W/System.err(4876):     at java.lang.Class.forName(Class.java:216)

03-11 01:52:54.804: W/System.err(4876):     at com.ansca.corona.NativeToJavaBridge.callLoadClass(NativeToJavaBridge.java:375)

03-11 01:52:54.804: W/System.err(4876):     at com.ansca.corona.JavaToNativeShim.nativeTapEvent(Native Method)

03-11 01:52:54.804: W/System.err(4876):     at com.ansca.corona.JavaToNativeShim.tapEvent(JavaToNativeShim.java:329)

03-11 01:52:54.804: W/System.err(4876):     at com.ansca.corona.input.RaiseTapEventTask.executeUsing(RaiseTapEventTask.java:43)

03-11 01:52:54.804: W/System.err(4876):     at com.ansca.corona.CoronaRuntimeTaskDispatcher$TaskEvent.Send(CoronaRuntimeTaskDispatcher.java:153)

03-11 01:52:54.804: W/System.err(4876):     at com.ansca.corona.events.EventManager.sendEvents(EventManager.java:229)

03-11 01:52:54.804: W/System.err(4876):     at com.ansca.corona.Controller.updateRuntimeState(Controller.java:222)

03-11 01:52:54.804: W/System.err(4876):     at com.ansca.corona.graphics.opengl.CoronaGLSurfaceView$CoronaRenderer.onDrawFrame(CoronaGLSurfaceView.java:402)

03-11 01:52:54.804: W/System.err(4876):     at com.ansca.corona.graphics.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1622)

03-11 01:52:54.804: W/System.err(4876):     at com.ansca.corona.graphics.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1377)

03-11 01:52:54.804: W/System.err(4876): Caused by: java.lang.NoClassDefFoundError: Util/LuaLoader

03-11 01:52:54.804: W/System.err(4876):     … 13 more

03-11 01:52:54.804: W/System.err(4876): Caused by: java.lang.ClassNotFoundException: Didn’t find class “Util.LuaLoader” on path: DexPathList[[zip file “/data/app/com.pseudios.SkitzShooter-1.apk”],nativeLibraryDirectories=[/data/app-lib/com.pseudios.SkitzShooter-1, /vendor/lib, /system/lib]]

03-11 01:52:54.804: W/System.err(4876):     at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)

03-11 01:52:54.804: W/System.err(4876):     at java.lang.ClassLoader.loadClass(ClassLoader.java:497)

03-11 01:52:54.814: W/System.err(4876):     at java.lang.ClassLoader.loadClass(ClassLoader.java:457)

03-11 01:52:54.814: W/System.err(4876):     … 13 more

03-11 01:52:54.814: I/Corona(4876): Runtime error

03-11 01:52:54.814: I/Corona(4876): module ‘Util’ not found:resource (Util.lu) does not exist in archive

03-11 01:52:54.814: I/Corona(4876):     no field package.preload[‘Util’]

03-11 01:52:54.814: I/Corona(4876):     no file ‘(null)/Util.lua’

03-11 01:52:54.814: I/Corona(4876):     no file ‘(null)/Util.lua’

03-11 01:52:54.814: I/Corona(4876):     no file ‘/data/app-lib/com.pseudios.SkitzShooter-1/libUtil.so’

03-11 01:52:54.814: I/Corona(4876):     no file ‘./Util.so’

03-11 01:52:54.814: I/Corona(4876):     no file ‘(null)/Util.so’

03-11 01:52:54.814: I/Corona(4876): stack traceback:

03-11 01:52:54.814: I/Corona(4876):     [C]: ?

03-11 01:52:54.814: I/Corona(4876):     [C]: in function ‘error’

03-11 01:52:54.814: I/Corona(4876):     ?: in function ‘gotoScene’

03-11 01:52:54.814: I/Corona(4876):     …ronaSDK Games/SkitzShooter/SkitzShooter/mainmenu.lua:28: in function <…ronaSDK Games/SkitzShooter/SkitzShooter/mainmenu.lua:27>

03-11 01:52:54.814: I/Corona(4876):     ?: in function <?:218>

03-11 01:52:54.814: I/Corona(4876): Runtime error

03-11 01:52:54.814: I/Corona(4876): stack traceback:

03-11 01:52:54.814: I/Corona(4876):     [C]: ?

03-11 01:52:54.814: I/Corona(4876):     [C]: in function ‘error’

03-11 01:52:54.814: I/Corona(4876):     ?: in function ‘gotoScene’

03-11 01:52:54.814: I/Corona(4876):     …ronaSDK Games/SkitzShooter/SkitzShooter/mainmenu.lua:28: in function <…ronaSDK Games/SkitzShooter/SkitzShooter/mainmenu.lua:27>

03-11 01:52:54.814: I/Corona(4876):     ?: in function <?:218>

Are you using Windows?

I always receive error on my Mac Simulator if the file does not exist

Nope. I am using OSX, simulator version 2013:2100.

After a bit more investigation, it seems that the filename will be accepted if it is the same word but in a different case.

E.G. 

[lua]require(“Util”)[/lua]

[lua]require(“UTil”)[/lua]

[lua]require(“utIL”)[/lua]

[lua]require(“UTIL”)[/lua]

are all accepted by the simulator.

My guess is that it either does a search for the filename if it happens to be incorrect and finds the closest match. Or, it will simply ignore the case altogether.

This doesn’t seem to be translated when the app is built though…

adarer

It has always been this way for as long as I can remember. The simulator doesn’t care if the case doesn’t match the filename of the Lua file, but the device does.

Always make sure that your filenames are the correct case. You can also wrap your require statements inside a pcall() to avoid causing a runtime error along with being able to print a message saying it failed to load the module etc.

http://docs.coronalabs.com/daily/api/library/global/pcall.html

This seems like a bit of an odd design/implementation choice for the simulator since it is known that there will be a runtime error on the device when the app is built if there is a bad filename…

There are vagaries that exist here, specifically, I believe that iOS is not case-sensitive, but I don’t have any devices to test this on at the moment.

See this thread. Rob weighed in and said that it’s actually the operating system that is disallowing case sensitivity, not the Corona SDK itself. 

Are you using Windows?

I always receive error on my Mac Simulator if the file does not exist

Nope. I am using OSX, simulator version 2013:2100.

After a bit more investigation, it seems that the filename will be accepted if it is the same word but in a different case.

E.G. 

[lua]require(“Util”)[/lua]

[lua]require(“UTil”)[/lua]

[lua]require(“utIL”)[/lua]

[lua]require(“UTIL”)[/lua]

are all accepted by the simulator.

My guess is that it either does a search for the filename if it happens to be incorrect and finds the closest match. Or, it will simply ignore the case altogether.

This doesn’t seem to be translated when the app is built though…

adarer

It has always been this way for as long as I can remember. The simulator doesn’t care if the case doesn’t match the filename of the Lua file, but the device does.

Always make sure that your filenames are the correct case. You can also wrap your require statements inside a pcall() to avoid causing a runtime error along with being able to print a message saying it failed to load the module etc.

http://docs.coronalabs.com/daily/api/library/global/pcall.html

This seems like a bit of an odd design/implementation choice for the simulator since it is known that there will be a runtime error on the device when the app is built if there is a bad filename…

There are vagaries that exist here, specifically, I believe that iOS is not case-sensitive, but I don’t have any devices to test this on at the moment.

See this thread. Rob weighed in and said that it’s actually the operating system that is disallowing case sensitivity, not the Corona SDK itself.