Potential ConcurrentException in MeshNetworkDb:InsertNetworkAsyncTask()
See original GitHub issueHello, I’d like to report a second bug found during importing a MeshNetwork (The first one and solution has been post under BubblyNetDev post named “Migration issue in 3.1.5”, not sure if it has been read and is planned to be fixed in next releases).
By the way, In class MeshNetworkDb.Java
Problem :
In class :
private static class InsertNetworkAsyncTask extends AsyncTask<Void, Void, Void> {
[...]
if (!meshNetwork.nodes.isEmpty()) {
nodesDao.insert(meshNetwork.nodes);
}
if (meshNetwork.groups != null) {
groupsDao.insert(meshNetwork.groups);
}
if (meshNetwork.scenes != null) {
scenesDao.insert(meshNetwork.scenes);
}
[...]
}
This can cause troubles down the line, in our case it caused several (still rare) ConcurrentExceptions :
Fatal Exception: java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$4.done(AsyncTask.java:415)
...
Caused by java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.next(ArrayList.java:860)
at androidx.room.EntityInsertionAdapter.insert(EntityInsertionAdapter.java:95)
at no.nordicsemi.android.meshprovisioner.data.ProvisionedMeshNodesDao_Impl.insert(ProvisionedMeshNodesDao_Impl.java:303)
at no.nordicsemi.android.meshprovisioner.MeshNetworkDb$InsertNetworkAsyncTask.doInBackground(MeshNetworkDb.java:307)
at no.nordicsemi.android.meshprovisioner.MeshNetworkDb$InsertNetworkAsyncTask.doInBackground(MeshNetworkDb.java:271)
Cause :
meshNetwork.nodes meshNetwork.groups and meshNetwork.scenes are arrayList. They can be modified from outside the MeshNetworkDb.java for any reason, it shouldn’t happen, but if it happens this leads to ConcurrentException.
Solution I fixed the problem cloning the arrayList before passing it to the Dao, this makes sure we never pass an array which could be potentially modified from outside:
if (!meshNetwork.nodes.isEmpty()) {
ArrayList<ProvisionedMeshNode> copyNodes = new ArrayList<>(meshNetwork.nodes);
nodesDao.insert(copyNodes);
}
Issue Analytics
- State:
- Created 2 years ago
- Comments:45 (23 by maintainers)

Top Related StackOverflow Question
I will use the approach that @Mavericksb has suggested since it’s a working solution. All updates and inserts will be done after copying the data in to a new list.
What is the line of code at MeshNetworkDb.java:149 ? If there is an array passed to an insert() method, just copy the array first, and then pass the copy to the insert method instead of the original array, to avoid concurrency.