updateProbe IllegalArgumentException

java.lang.IllegalArgumentException: Error writeComponents { 24576, 1 }
        at com.jme3.texture.image.MipMapImageRaster.setPixel(MipMapImageRaster.java:134)
        at com.jme3.environment.util.CubeMapWrapper.setPixel(CubeMapWrapper.java:230)
        at com.jme3.environment.generation.PrefilteredEnvMapFaceGenerator.generatePrefilteredEnvMap(PrefilteredEnvMapFaceGenerator.java:188)
        at com.jme3.environment.generation.PrefilteredEnvMapFaceGenerator.run(PrefilteredEnvMapFaceGenerator.java:135)
        at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
        at java.util.concurrent.FutureTask.run(Unknown Source)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(Unknown Source)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalArgumentException: Error setting position { 30276, 32760, 32760 }
        at com.jme3.texture.image.ByteAlignedImageCodec.writePixelRaw(ByteAlignedImageCodec.java:71)
        at com.jme3.texture.image.ByteAlignedImageCodec.writeComponents(ByteAlignedImageCodec.java:131)
        at com.jme3.texture.image.MipMapImageRaster.setPixel(MipMapImageRaster.java:132)
        ... 10 more
Caused by: java.lang.IllegalArgumentException
        at java.nio.Buffer.position(Unknown Source)
        at com.jme3.texture.image.ByteAlignedImageCodec.writePixelRaw(ByteAlignedImageCodec.java:69)
        ... 12 more
While java.lang.IllegalArgumentException: Error writeComponents { 24576, 1 }
    at com.jme3.texture.image.MipMapImageRaster.setPixel(MipMapImageRaster.java:134)
    at com.jme3.environment.util.CubeMapWrapper.setPixel(CubeMapWrapper.java:230)
    at com.jme3.environment.generation.PrefilteredEnvMapFaceGenerator.generatePrefilteredEnvMap(PrefilteredEnvMapFaceGenerator.java:188)
    at com.jme3.environment.generation.PrefilteredEnvMapFaceGenerator.run(PrefilteredEnvMapFaceGenerator.java:135)
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(Unknown Source)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalArgumentException: Error setting position { 30276, 32760, 32760 }
    at com.jme3.texture.image.ByteAlignedImageCodec.writePixelRaw(ByteAlignedImageCodec.java:71)
    at com.jme3.texture.image.ByteAlignedImageCodec.writeComponents(ByteAlignedImageCodec.java:131)
    at com.jme3.texture.image.MipMapImageRaster.setPixel(MipMapImageRaster.java:132)
    ... 10 more
Caused by: java.lang.IllegalArgumentException
    at java.nio.Buffer.position(Unknown Source)
    at com.jme3.texture.image.ByteAlignedImageCodec.writePixelRaw(ByteAlignedImageCodec.java:69)
    ... 12 more

@nehon following our discussion i’ve made some additional exception handling to find the reason for this (already in the exception above)

In MipMapImageRaster.java:

try {
            codec.writeComponents(getBuffer(), x, y, width[mipLevel], offsets[mipLevel], components, temp);
        } catch (IllegalArgumentException iae) {
            throw new IllegalArgumentException("Error writeComponents { " + offsets[mipLevel] + ", " + mipLevel + " }", iae);
        }        

And in ByteAlignedImageCodec.java

try {
            buf.position(idx);            
        } catch (IllegalArgumentException iae) {
            throw new IllegalArgumentException("Error setting position { " + idx + ", " + buf.limit() + ", " + buf.capacity() + " }", iae);
        }

So if i am not mistaken we get an IllegalArgumentException when setting position 30276 even if the limit and the capacity is both 32760 for the buffer

So 30276 < 32760, right? What other reasons are there for position() to cause an IllegalArgumentException?

Anyway, because you’ve asked. This is the way the probe is updated:

public void updateProbe(final JobProgressAdapter<LightProbe> progressAdapter) {
        final LightProbe lightProbe = getLightProbe();

        if (lightProbe == null) {
            progressAdapter.done(null);
            return;
        }

        LightProbeFactory.updateProbe(lightProbe, getEnvironmentCamera(), rootNode, progressAdapter);
    }

Like said before, this only happens in my complete application and i cannot make a simple test-case - so i am pretty sure the root is somewhere in my code, which you cannot see;) But maybe you have a clue and we can improve exception handling to make it more obvious the next time somebody gets this kind of stacktrace.

2 Likes

I have found roughly the reason and a solution. This exception happens when updateProbe gets called before a previous call has been finished. Didn’t check it in detail but I assume two threads are trying to modify the same buffer. The first solution i tried was using the progressAdapter to ensure no overlapping runs:

public final JobProgressAdapter<LightProbe> SINGLE_JOB_ADAPTER = new JobProgressAdapter<LightProbe>() {
        @Override
        public void start() {
            _probeUpdateRunning = true;
        }
        @Override
        public void done(final LightProbe result) {
            _probeUpdateRunning = false;
        }
    };

First I thought it clever to also utilize the start method, but that alone did not do the trick because the start method gets actually called somewhere in the middle of the update process. So I had to do this as well:

public void updateProbe(final JobProgressAdapter<LightProbe> progressAdapter) {
        final LightProbe lightProbe = getLightProbe();
        
        if( _probeUpdateRunning )
            return;

        if (lightProbe == null) {
            progressAdapter.done(null);
            return;
        }
                
        _probeUpdateRunning = true;
        LightProbeFactory.updateProbe(lightProbe, getEnvironmentCamera(), rootNode, progressAdapter);
    }

So now i don’t get the exception anymore… But i think this condition should be somewhere ensured in the LightProbeFactory.

The interesting thing is, that I tried to replicate this error in a separate test, but there everything was working just fine even when calling updateProbe 1000 times before its finished - so there is a second condition for this error somewhere…

1 Like

ha thanks for the update!!

1 Like

I think i will have a deeper look into this and find a proper solution “soonish”. But today i am not in the right mood :wink:

2 Likes