Pontential Issue with collideWith & sorting

Using collideWith now throws the following exception… I pretty sure it did not until recently.

[java]SEVERE: null
java.util.concurrent.ExecutionException: java.util.ConcurrentModificationException
at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222)
at java.util.concurrent.FutureTask.get(FutureTask.java:83)
at paging.core.ManagedMeshDelegator.delegateTasks(ManagedMeshDelegator.java:250)
at paging.core.ManagedMeshDelegator.update(ManagedMeshDelegator.java:51)
at com.jme3.scene.Spatial.runControlUpdate(Spatial.java:559)
at com.jme3.scene.Spatial.updateLogicalState(Spatial.java:677)
at com.jme3.scene.Node.updateLogicalState(Node.java:145)
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:243)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:151)
at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:185)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:228)
at java.lang.Thread.run(Thread.java:619)
Caused by: java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:349)
at java.util.Collections.sort(Collections.java:120)
at com.jme3.collision.CollisionResults.getClosestCollision(CollisionResults.java:84)
at com.jme3.collision.bih.BIHTree.collideWithRay(BIHTree.java:404)
at com.jme3.collision.bih.BIHTree.collideWith(BIHTree.java:456)
at com.jme3.scene.Mesh.collideWith(Mesh.java:853)
at com.jme3.scene.Geometry.collideWith(Geometry.java:454)
at com.jme3.scene.Node.collideWith(Node.java:492)
at pagingTests.supportFiles.TerrainSimpleTree.applyToTerrainGrid(TerrainSimpleTree.java:100)
at pagingTests.supportFiles.TerrainSimpleTreeDelegator.createMesh(TerrainSimpleTreeDelegator.java:94)
at paging.core.ManagedMeshDelegator$3.call(ManagedMeshDelegator.java:237)
at paging.core.ManagedMeshDelegator$3.call(ManagedMeshDelegator.java:234)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:98)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:207)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)[/java]

Was this changed recently? In particular:

[java]Caused by: java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:349)
at java.util.Collections.sort(Collections.java:120)
at com.jme3.collision.CollisionResults.getClosestCollision(CollisionResults.java:84)[/java]

Guess it’s worth mentioning, this happens even if I clone the node.

Are you performing collision tests from a background thread? I’m not sure that’s a good idea.

Other than that, are you sure you aren’t somehow reusing collision results objects? Across threads maybe?

@pspeed I thought so too but it seems she’s a good monkey and enqueues, no? Anyway I thought of concurrent collision data generation first too but it doesn’t seem to be it… We didn’t change this code lately did we? Some list stuff or so? @t0neg0d Can you make a test case ? :smiley:

Sorry for the delay… bit under the weather today

Let me ask a few questions first to see if I made a bad assumption or three in some of the test delegators I’ve been trying out. (These have nothing to do with the paging system… there trying different ideas for randomly placing objects, etc)

  1. You can ray cast into a Node that is not associated with the scene graph being rendered… and this is ok, yes?
  2. If this is the case, then you shouldn’t need to enqueue a ray casting, yes?
  3. @pspeed mentioned the reusing of collisions results object. Is this a problem even if you use .clear(); ?

Oh… to answer the background thread question, I am. However, it is using a node that is a “point 1.” above scenario.

@normen While I’m waiting for the answers… I’ll give a few things a shot. Trying to figure out how to put together a simple test case for this. If I update the pagingTest project in the contributors depot… there would be one there. However, it would not be a “simple” test case.

Pretend I quoted the crap out of all of that. :evilmonkey:

  1. Only if you do it from one thread. Collisions against an unattached node from multiple threads may be bad if the collision data has not been generated or whatever.

  2. Depends. See above.

  3. a) there is really no reason to reuse collision results. b) it may lead to an error of using the same collision results object from two different threads, ie: trying to perform two ray casts at the same time with the same collision results. That’s really the only way that I can see getting a concurrent mod exception with that class. It’s not like it shares state with anything else once the results are collected.

@normen, she’s doing stuff from different threads from the paging system. Even in the above there is at least one other thread hitting stuff.

Actually, so I checked the source and this has nothing to do with your own CollisionResults. The CollisionResults that is being conc-modded is internal to the BIHTree. So, the same node is having multiple collisions run against it from different threads.

Yea indeed, I misinterpreted the output… Its definitely too late now to be of any use, I go to bed xD

First no quoting… now no evil monkey. /me is depressed. :-/

You need to call Spatial#updateGeometricState on a not-attached-to-the-scenegraph-node before using it. jME is doing this for all Spatials attached on every frame, but not on unattached spatials.

Be warned though, this might lead you down a path you are not supposed to walk…

…and has nothing to do with this error.

pspeed is right, do not listen to me.

1 Like

Hi, what was the outcome about this issue? I’m getting the same random exceptions in a very similar situation (background thread raycasting).

@.Ben. said: Hi, what was the outcome about this issue? I'm getting the same random exceptions in a very similar situation (background thread raycasting).

Well you’re not supposed to raycast in a live scene from another thread…

Let’s say I want to find the contact points of a thousand spatials along the edge of another spatial, I would greatly make use of another thread to do that while my scene continues to refresh? None of the spatials used in the collision method are attached to the rootNode nor used by OpenGL to draw on the screen, so I must have missed the point of the collideWith, but what’s related between the spatial collision and the geometry drawing on the screen? Why aren’t both possible concurrently?

EDIT: NO WAIT. Actually, I discovered a flaw in my code. It was indeed reusing a node previously attached to the rootNode. My mistake :stuck_out_tongue: I’ll test some more making absolutely sure it does not use any node attached to the rootNode.

EDIT #2: Confirmed. It works just fine from a thread given that it is NOT attached to the rootNode (my mistake to assume it was not, when smoehow I foresaw it really was) It works as expected now.