JDK-6967419 : IndexOutOfBoundsException when drawing PNGs
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.imageio
  • Affected Version: 6u20,8,9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2010-07-07
  • Updated: 2016-01-07
  • Resolved: 2015-12-01
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9 b100Fixed
Related Reports
Duplicate :  
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) Client VM (build 16.3-b01, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Windows XP SP3

EXTRA RELEVANT SYSTEM CONFIGURATION :
n/a
Used a ServletOutputStream, connected to localhost.

A DESCRIPTION OF THE PROBLEM :
When drawing PNG images to a ServletOutputStream using the following method:
            javax.imageio.ImageIO.write(image, "png", outStream);

I receive the following stack trace:

java.lang.IndexOutOfBoundsException
at javax.imageio.stream.FileCacheImageOutputStream.seek(FileCacheImageOutputStream.java:151)
at javax.imageio.stream.FileCacheImageOutputStream.close(FileCacheImageOutputStream.java:212)
at javax.imageio.ImageIO.write(ImageIO.java:1567)
... (our code)

After some investigation, I've found that in javax.imageio.stream.FileCacheImageOutputStream.seek(), flushedPos is set to 4 bytes past the end of the cache file, which causes the exception when the stream is flushed since 'pos' is the actual end of the file, and is before the 'flushedPos'.

This bug does not always happen. In 20 draws it would occur anywhere from 3-7 times. (It's a mapping application, and the draws are map tiles.)

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Create an OutputStream.
2. Load a PNG file into memory.
3. Use the javax.imageio.ImageIO.write method to write the image to the stream.



EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The image should draw, there should be no exception thrown, and the cache file should be deleted.
ACTUAL -
The image draws, but there is an exception thrown, and the cache file remains in the cache directory.

REPRODUCIBILITY :
This bug can be reproduced occasionally.

CUSTOMER SUBMITTED WORKAROUND :
Use a memory cache.

Comments
When user intentionally throws IO Exception while stream.write() is happening. Only in case write_IDAT we have finally block which calls ios.finish(), which internally goes to finishChunk(). Only after finishChunk() is done we call startChunk() to update startPos. But in this test case we are intentionally stopping write. So again when call comes to finishChunk(), startPos will be less than flushedPos(streamPos) and it causes IndexOutOfBoundsException while seek() is happening. So in finishChunk(), startPos will be less than flushedPos. This is causing IndexOutOfBoundsException in stream.seek(). So added try catch block when flushBefore() is happening so that we can catch IOException and update startPos so that there will be no IndexOutOfBoundsException and cache closes properly.
13-11-2015

Attached test demonstrates a possible scenario to run int the problem: if output stream throws an IO exception, then we have got the described IndexOutOfBoundsException on an attempt to close the cached output stream.
08-05-2014

added sustaining label since that is assigned to Andrew
08-05-2014