B4J Question Index Out Of Bound Exception

Didier9

Well-Known Member
Licensed User
Longtime User
I get this error:

B4X:
Error occurred on line: 422
java.lang.ArrayIndexOutOfBoundsException
    at java.lang.reflect.Array.get(Native Method)
    at anywheresoftware.b4a.shell.ArraysUtils.getElement(ArraysUtils.java:76)
    at anywheresoftware.b4a.shell.Shell.getArrayElement(Shell.java:482)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:269)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:167)
    at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:91)
    at anywheresoftware.b4a.shell.ShellBA.raiseEvent2(ShellBA.java:98)
    at anywheresoftware.b4a.debug.Debug.delegate(Debug.java:64)
    at b4j.example.main._processtargetblinfoblock(main.java:713)
    at b4j.example.main._astream_newdata(main.java:609)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:632)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:237)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:167)
    at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:91)
    at anywheresoftware.b4a.shell.ShellBA.raiseEvent2(ShellBA.java:98)
    at anywheresoftware.b4a.BA$2.run(BA.java:230)
    at com.sun.javafx.application.PlatformImpl.lambda$null$5(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$6(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$3(WinApplication.java:177)
    at java.lang.Thread.run(Thread.java:748)

when running this function:

B4X:
Sub GetFieldIndex( fn As String ) As Int
    Dim i As Int
    For i=0 To FieldName.Length-1
        'Log( fn & ", " & FieldName(i) )
        If fn = FieldName(i) Then Exit
    Next
    If i = FieldName.Length Then i = -1
    Return i ' <=== line 422
End Sub ' GetFieldIndex()

Strangely enough, it fails the second tine I call this function with the argument "CRC Type", which searches through a string array for a matching string.
The first time it works as intended.
Of course, the string I provide matches one of the entry. It is the last entry in the array.

Here is the array declaration:

B4X:
    Dim FieldName() As String
    FieldName  = Array As String( "InfoBlock Length", "MCU Code", "BL Type", "Flash Page Size", "App FW Version", "BL Specific", "Signature", _
            "App Start Addr", "App End Addr", "BL FW Version", "BL Buffer Size", "CRC Type" )

Why does it fail on the Return statement instead of the line that fetches the array element, if it actually were an out of bound condition?
Why doesn't it fail on the first call to that function with the same argument?
I have rewritten the function a number of times, even including a Try-Catch block, which does not catch the error by the way :(

I forgot to add that this code in its own project does not fail, so it could be related to something else happening in my code but I have no idea what.
Any help appreciated.
 

Didier9

Well-Known Member
Licensed User
Longtime User
Hi Enrique,
I will post that code tomorrow but it sounds like you may be right. The function returns an argument directly used in another function, there is no intermediate line of code with a variable assigned to the return value. This is something that I normally avoid doing precisely because it makes debugging more difficult but in this case I have a lot of similar calls so I did it to reduce the code size. I will check in the morning when I am back working on that project.
Thanks for the pointer!
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
O.T. I would like it more like this:
B4X:
Sub GetFieldIndex( fn As String ) As Int
    Dim Index As Int = -1 ' not found.
    For i = 0 To FieldName.Length - 1
        If FieldName(i) = fn Then
            Index = i
            Exit
        End If
    Next
    Return Index
End Sub ' GetFieldIndex()

or, better:
B4X:
FieldIndex = lstFieldNames.IndexOf(fn)
where lstFieldNames is a List, instead of an Array.
;)

B4X:
    Dim lstFieldNames As List
    lstFieldNames.Initialize2(Array As String( "InfoBlock Length", "MCU Code", "BL Type", "Flash Page Size", "App FW Version", "BL Specific", "Signature", _
            "App Start Addr", "App End Addr", "BL FW Version", "BL Buffer Size", "CRC Type" ))

    Log("(Field) Index of 'CRC Type' = " & lstFieldNames.IndexOf("CRC Type"))
 
Last edited:
Upvote 0

Didier9

Well-Known Member
Licensed User
Longtime User
Luca,
Your first suggestion is pretty much what I had originally, I rewrote it as an attempt to isolate what was going on...
But I like your second suggestion better :) very elegant!
I am still very much underutilizing lists...

Enrique,
You did correctly identify the problem. This is the line of code that was calling this function:
B4X:
SetTvCellValue( GetFieldIndex( "CRC Type" ), 2, BLInfoBlock.crctype & ", " & CRCTypeTxt( i ), tvSettings )
The problem was that I was out of bounds on the CRCTypeTxt() array. Not at all related to the GetFieldIndex() function, but Java was crashing right after returning the value and for some reason the debugger could not return the actual line of code where it crashed.
Not very intuitive but hopefully I will remember that for next time...

It's all working now, thank you both!
 
Upvote 0

Didier9

Well-Known Member
Licensed User
Longtime User
Sorry, I was not clear still...

What I meant was your first version was very similar to what I had before I started modifying the code into what I posted at the beginning of this thread. As I said, I messed with it for a while trying to understand where it was crashing before I posted. As is often the case, the problem was not where I was looking for.

Thank you!
 
Upvote 0
Top