6657133: Mutable statics in imageio plugins (findbugs)

Reviewed-by: prr
This commit is contained in:
Andrew Brygin 2009-05-08 15:57:33 +04:00
parent 10f62128a4
commit 8fdb1d367a
7 changed files with 51 additions and 21 deletions

View File

@ -43,35 +43,35 @@ import javax.imageio.stream.ImageInputStream;
*/
public class StreamCloser {
private static WeakHashMap<ImageInputStream, Object> toCloseQueue;
private static WeakHashMap<CloseAction, Object> toCloseQueue;
private static Thread streamCloser;
public static void addToQueue(ImageInputStream iis) {
public static void addToQueue(CloseAction ca) {
synchronized (StreamCloser.class) {
if (toCloseQueue == null) {
toCloseQueue =
new WeakHashMap<ImageInputStream, Object>();
new WeakHashMap<CloseAction, Object>();
}
toCloseQueue.put(iis, null);
toCloseQueue.put(ca, null);
if (streamCloser == null) {
final Runnable streamCloserRunnable = new Runnable() {
public void run() {
if (toCloseQueue != null) {
synchronized (StreamCloser.class) {
Set<ImageInputStream> set =
Set<CloseAction> set =
toCloseQueue.keySet();
// Make a copy of the set in order to avoid
// concurrent modification (the is.close()
// will in turn call removeFromQueue())
ImageInputStream[] streams =
new ImageInputStream[set.size()];
streams = set.toArray(streams);
for (ImageInputStream is : streams) {
if (is != null) {
CloseAction[] actions =
new CloseAction[set.size()];
actions = set.toArray(actions);
for (CloseAction ca : actions) {
if (ca != null) {
try {
is.close();
ca.performAction();
} catch (IOException e) {
}
}
@ -106,10 +106,28 @@ public class StreamCloser {
}
}
public static void removeFromQueue(ImageInputStream iis) {
public static void removeFromQueue(CloseAction ca) {
synchronized (StreamCloser.class) {
if (toCloseQueue != null) {
toCloseQueue.remove(iis);
toCloseQueue.remove(ca);
}
}
}
public static CloseAction createCloseAction(ImageInputStream iis) {
return new CloseAction(iis);
}
public static final class CloseAction {
private ImageInputStream iis;
private CloseAction(ImageInputStream iis) {
this.iis = iis;
}
public void performAction() throws IOException {
if (iis != null) {
iis.close();
}
}
}

View File

@ -78,7 +78,7 @@ public class BMPImageWriteParam extends ImageWriteParam {
super(locale);
// Set compression types ("BI_RGB" denotes uncompressed).
compressionTypes = BMPConstants.compressionTypeNames;
compressionTypes = BMPConstants.compressionTypeNames.clone();
// Set compression flag.
canWriteCompressed = true;

View File

@ -62,6 +62,10 @@ public class FileCacheImageInputStream extends ImageInputStreamImpl {
/** The DisposerRecord that closes the underlying cache. */
private final DisposerRecord disposerRecord;
/** The CloseAction that closes the stream in
* the StreamCloser's shutdown hook */
private final StreamCloser.CloseAction closeAction;
/**
* Constructs a <code>FileCacheImageInputStream</code> that will read
* from a given <code>InputStream</code>.
@ -96,7 +100,9 @@ public class FileCacheImageInputStream extends ImageInputStreamImpl {
this.cacheFile =
File.createTempFile("imageio", ".tmp", cacheDir);
this.cache = new RandomAccessFile(cacheFile, "rw");
StreamCloser.addToQueue(this);
this.closeAction = StreamCloser.createCloseAction(this);
StreamCloser.addToQueue(closeAction);
disposerRecord = new StreamDisposerRecord(cacheFile, cache);
if (getClass() == FileCacheImageInputStream.class) {
@ -242,7 +248,7 @@ public class FileCacheImageInputStream extends ImageInputStreamImpl {
stream = null;
cache = null;
cacheFile = null;
StreamCloser.removeFromQueue(this);
StreamCloser.removeFromQueue(closeAction);
}
/**

View File

@ -48,6 +48,10 @@ public class FileCacheImageOutputStream extends ImageOutputStreamImpl {
// Pos after last (rightmost) byte written
private long maxStreamPos = 0L;
/** The CloseAction that closes the stream in
* the StreamCloser's shutdown hook */
private final StreamCloser.CloseAction closeAction;
/**
* Constructs a <code>FileCacheImageOutputStream</code> that will write
* to a given <code>outputStream</code>.
@ -82,7 +86,9 @@ public class FileCacheImageOutputStream extends ImageOutputStreamImpl {
this.cacheFile =
File.createTempFile("imageio", ".tmp", cacheDir);
this.cache = new RandomAccessFile(cacheFile, "rw");
StreamCloser.addToQueue(this);
this.closeAction = StreamCloser.createCloseAction(this);
StreamCloser.addToQueue(closeAction);
}
public int read() throws IOException {
@ -227,7 +233,7 @@ public class FileCacheImageOutputStream extends ImageOutputStreamImpl {
cacheFile = null;
stream.flush();
stream = null;
StreamCloser.removeFromQueue(this);
StreamCloser.removeFromQueue(closeAction);
}
public void flushBefore(long pos) throws IOException {

View File

@ -127,7 +127,7 @@ system.scope=sun.security.provider.IdentityDatabase
# passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted.
package.access=sun.
package.access=sun.,com.sun.imageio.
#
# List of comma-separated packages that start with or equal this string

View File

@ -128,7 +128,7 @@ system.scope=sun.security.provider.IdentityDatabase
# passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted.
package.access=sun.
package.access=sun.,com.sun.imageio.
#
# List of comma-separated packages that start with or equal this string

View File

@ -128,7 +128,7 @@ system.scope=sun.security.provider.IdentityDatabase
# passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted.
package.access=sun.
package.access=sun.,com.sun.imageio.
#
# List of comma-separated packages that start with or equal this string