Android Question java.lang.IndexOutOfBoundsException when using StartServiceAt

Michael2150

Member
Licensed User
I have a service that tries to sync events to a server. The service tries syncing it, but if an error occurs the service restarts a certain amount of time later. This only happens a set amount of times before the service gives up and then I use StartServiceAt to start a second service a much later time to try and restart the first service from the beginning trying to sync the events again.
For some unknown reason I get the error "java.lang.IndexOutOfBoundsException: Index: 3, Size: 2" when trying to queue the second service to start.

[CODE lang="b4x" title="The global variables"]Sub Process_Globals
Public AlreadyQueuedToStart As Boolean = False 'This is used to check if the SyncFailedEvent is already queued to start
Private RetryFailedTime As Int = 0.5 * DateTime.TicksPerMinute 'minutes The time to wait before retrying to synced a failed event
End Sub[/CODE]

[CODE lang="b4x" title="The code where the error happens" highlight="4"]If Not(AlreadyQueuedToStart) Then
Log("Sync failed events queued to start")
StartServiceAtExact(SyncFailedEvents, DateTime.Now + RetryFailedTime ,True)
AlreadyQueuedToStart = True
End If[/CODE]
 
Are you sure that line is causing the error?
 
Upvote 0
What might be the problem?
Maybe not posting the relevant code.

I don´t see you are accessing a list or array which can raise such errors in the code you posted.

Start with posting the FULL ERROR
 
Upvote 0
[CODE lang="b4x" title="This is the whole sub the highlighted line is where the IDE shows the error occurs" highlight="32"]Sub Sync
If Not(Syncing) Then
Syncing = True
ErrorOccured = False

LogColor($"SyncService Starting..."$,Colors.Green)

If File.Exists(File.DirInternal,MapFileSaveName) Then
RetryMap = File.ReadMap(File.DirInternal,MapFileSaveName)
End If

UnsyncedEvents = DataAccess.GetEventsWithoutSync
If UnsyncedEvents.Size = 0 Then StopService(Me)

For Each Event As WorkorderEvent In UnsyncedEvents
Dim Key As String = Event.id
Dim Attempts As String = "0"
If Not(RetryMap.ContainsKey(Key)) Then
RetryMap.Put(Key,Attempts)
End If
Attempts = RetryMap.Get(Key)

If Attempts >= RetryLimit Then
LogColor($"Event retry limit reached EventId:${Event.id}"$,Colors.Red)
DataAccess.InsertRemoteID(0,Event.id)
RemoveEventFromList(Event)
RetryMap.Remove(Key)

If Not(AlreadyQueuedToStart) Then
Log("Sync failed events queued to start")
StartServiceAtExact(SyncFailedEvents, DateTime.Now + RetryFailedTime ,True)
AlreadyQueuedToStart = True
End If
Else
LogColor($"Try Sync: EventID: ${Event.id} attempt: ${RetryMap.Get(Key)}"$,Colors.Magenta)
API.CreateEvent(Event)
AddOnMap(Event)
End If
Next
If UnsyncedEvents.Size = 0 Then StopService(Me)
Else
LogColor($"ShouldTryAgain = True"$,Colors.Yellow)
ShouldStartAgain = True
End If
End Sub[/CODE]

That is the whole sub with the line where the IDE says the Error occurs the full error is:


1590576199607.png
 
Upvote 0
Upvote 0
Is this in Debug or Release mode?
The error happens in both modes.. This is really confusing because I'm not really using lists except for the for each loop and the Map. When using a breakpoint at the if statement it runs through without any problems though.
 
Upvote 0
In release mode, when the exception occurs, the exception report (stack trace) will include the line in the syncevents.java file (the source that is produced by B4A in Objects\src\com\eureka\dispatchit folder) where the exception happens. Find the relevant line (for example in the screenshot above, it was line 407) and post it plus some lines above and below.
Note #1: don't post a screenshot, post the lines. Also, post the exception (to verify the line that is causing it).
Note #2: I may have a typo in my source location folder. Don't let that deter you in finding it.
 
Upvote 0
Ah I see I ran it in release mode and got the error:

syncevents_sync (java line: 349)
java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
at java.util.ArrayList.get(ArrayList.java:437)
at anywheresoftware.b4a.objects.collections.List.Get(List.java:117)
at com.eureka.dispatchit.syncevents._sync(syncevents.java:349)
at com.eureka.dispatchit.syncevents._service_start(syncevents.java:315)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:196)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:176)
at com.eureka.dispatchit.syncevents.handleStart(syncevents.java:100)
at com.eureka.dispatchit.syncevents.access$000(syncevents.java:8)
at com.eureka.dispatchit.syncevents$1.run(syncevents.java:71)
at anywheresoftware.b4a.objects.ServiceHelper$StarterHelper.onStartCommand(ServiceHelper.java:237)
at com.eureka.dispatchit.syncevents.onStartCommand(syncevents.java:69)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:4298)
at android.app.ActivityThread.access$2700(ActivityThread.java:273)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2070)
at android.os.Handler.dispatchMessage(Handler.java:112)
at android.os.Looper.loop(Looper.java:216)
at android.app.ActivityThread.main(ActivityThread.java:7625)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)

So I had a look at Java line 349 and found the for each loop


[CODE lang="b4x" title="Java code for the for each loop." highlight="2"]for (; index10 < groupLen10;index10++){
_event = (com.eureka.dispatchit.workorderevent)(group10.Get(index10));
//BA.debugLineNum = 49;BA.debugLine="Dim Key As String = Event.id";
_key = BA.NumberToString(_event._id /*int*/ );
//BA.debugLineNum = 50;BA.debugLine="Dim Attempts As String = \"0\"";
_attempts = "0";
//BA.debugLineNum = 51;BA.debugLine="If Not(RetryMap.ContainsKey(Key)) Then";
if (anywheresoftware.b4a.keywords.Common.Not(_retrymap.ContainsKey((Object)(_key)))) {
//BA.debugLineNum = 52;BA.debugLine="RetryMap.Put(Key,Attempts)";
_retrymap.Put((Object)(_key),(Object)(_attempts));
};
//BA.debugLineNum = 54;BA.debugLine="Attempts = RetryMap.Get(Key)";
_attempts = BA.ObjectToString(_retrymap.Get((Object)(_key)));
//BA.debugLineNum = 56;BA.debugLine="If Attempts >= RetryLimit Then";
if ((double)(Double.parseDouble(_attempts))>=_retrylimit) {
//BA.debugLineNum = 57;BA.debugLine="LogColor($\"Event retry limit reached EventId:$";
anywheresoftware.b4a.keywords.Common.LogImpl("47536663",("Event retry limit reached EventId:"+anywheresoftware.b4a.keywords.Common.SmartStringFormatter("",(Object)(_event._id /*int*/ ))+""),anywheresoftware.b4a.keywords.Common.Colors.Red);
//BA.debugLineNum = 58;BA.debugLine="DataAccess.InsertRemoteID(0,Event.id)";
mostCurrent._dataaccess._insertremoteid /*String*/ (processBA,(int) (0),_event._id /*int*/ );
//BA.debugLineNum = 59;BA.debugLine="RemoveEventFromList(Event)";
_removeeventfromlist(_event);
//BA.debugLineNum = 60;BA.debugLine="RetryMap.Remove(Key)";
_retrymap.Remove((Object)(_key));
//BA.debugLineNum = 62;BA.debugLine="If Not(AlreadyQueuedToStart) Then";
if (anywheresoftware.b4a.keywords.Common.Not(_alreadyqueuedtostart)) {
//BA.debugLineNum = 63;BA.debugLine="Log(\"Sync failed events queued to start\")";
anywheresoftware.b4a.keywords.Common.LogImpl("47536669","Sync failed events queued to start",0);
//BA.debugLineNum = 64;BA.debugLine="StartServiceAtExact(SyncFailedEvents, DateTim";
anywheresoftware.b4a.keywords.Common.StartServiceAtExact(processBA,(Object)(mostCurrent._syncfailedevents.getObject()),(long) (anywheresoftware.b4a.keywords.Common.DateTime.getNow()+_retryfailedtime),anywheresoftware.b4a.keywords.Common.True);
//BA.debugLineNum = 65;BA.debugLine="AlreadyQueuedToStart = True";
_alreadyqueuedtostart = anywheresoftware.b4a.keywords.Common.True;
};
}else {
//BA.debugLineNum = 68;BA.debugLine="LogColor($\"Try Sync: EventID: ${Event.id} atte";
anywheresoftware.b4a.keywords.Common.LogImpl("47536674",("Try Sync: EventID: "+anywheresoftware.b4a.keywords.Common.SmartStringFormatter("",(Object)(_event._id /*int*/ ))+" attempt: "+anywheresoftware.b4a.keywords.Common.SmartStringFormatter("",_retrymap.Get((Object)(_key)))+""),anywheresoftware.b4a.keywords.Common.Colors.Magenta);
//BA.debugLineNum = 69;BA.debugLine="API.CreateEvent(Event)";
_api._createevent /*String*/ (_event);
//BA.debugLineNum = 70;BA.debugLine="AddOnMap(Event)";
_addonmap(_event);
};
}[/CODE]

The highlighted line is the line 349 the error message included. And i can now see it was the list I used.
 
Upvote 0
For Each Event As WorkorderEvent In UnsyncedEvents
Are you modifying UnsyncedEvents in this For Each Loop? You can't do that. If you delete items of UnsyncedEvents during the For Each processing, you can cause an exception. You need to determine what you want to add/delete from UnsyncedEvents in the For Each loop and then do your additions/deletions outside of the For Each loop.
 
Upvote 0
I think that might be the problem. It makes sense now that I think about it ? and I feel stupid. Ill try and fix it and let you know if it worked.
 
Upvote 0
Yes that works perfectly now. Thank you for the help. I've actually never debugged using the Java code. But I'm glad I learned something new though.
 
Upvote 0
Back
Top