JDK-6560950 : A method that should throw an exception but it does not
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.imageio
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2007-05-23
  • Updated: 2014-05-07
  • Resolved: 2014-05-07
Related Reports
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
Package: "com.sun.imageio.spi"
File: "FileImageOutputStreamSpi.java"
Method: "createOutputStreamInstance"

DESCRIPTION
============
This method should throw a FileNotFoundException, so it can be handled on the callers, but instead (for some unknown reason to me) it prints the stack and returns null.

I wanted to catch the FileNotFoundException on my method in order to take care of the problem, but that's impossible with the current implementation.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Check this stacktrace:
java.io.FileNotFoundException: \Docs\University\4th Year\2nd Semester\dbi\www\cache\icons\File_Folder.png (The system cannot find the path specified)
	at java.io.RandomAccessFile.open(Native Method)
	at java.io.RandomAccessFile.<init>(RandomAccessFile.java:212)
	at javax.imageio.stream.FileImageOutputStream.<init>(FileImageOutputStream.java:53)
	at com.sun.imageio.spi.FileImageOutputStreamSpi.createOutputStreamInstance(FileImageOutputStreamSpi.java:37)
	at javax.imageio.ImageIO.createImageOutputStream(ImageIO.java:393)
	at javax.imageio.ImageIO.write(ImageIO.java:1514)

----- (from here is all mine) --------
	at webServer.IconManager.storeIcon(IconManager.java:64)
	at webServer.IconManager.getIcon(IconManager.java:51)
	at webServer.DirectoryHandler.handleRequest(DirectoryHandler.java:95)
	at webServer.RequestHandlerThread.run(RequestHandlerThread.java:72)

  To reproduce it just try to use the ImageIO.write method on an nonexistent path (that can be created with mkdirs()). You'll get this bug even if you try and catch on upper classes the FileNotFoundException.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Simply that every Exception will be thrown so the caller can catch it and take the necessary actions.
ACTUAL -
I printed before the stacktrace and described all what I saw.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
This wasn't a crash. Here's the stacktraccce again:

java.io.FileNotFoundException: \Docs\University\4th Year\2nd Semester\dbi\www\cache\icons\File_Folder.png (The system cannot find the path specified)
	at java.io.RandomAccessFile.open(Native Method)
	at java.io.RandomAccessFile.<init>(RandomAccessFile.java:212)
	at javax.imageio.stream.FileImageOutputStream.<init>(FileImageOutputStream.java:53)
	at com.sun.imageio.spi.FileImageOutputStreamSpi.createOutputStreamInstance(FileImageOutputStreamSpi.java:37)
	at javax.imageio.ImageIO.createImageOutputStream(ImageIO.java:393)
	at javax.imageio.ImageIO.write(ImageIO.java:1514)
	at webServer.IconManager.storeIcon(IconManager.java:64)
	at webServer.IconManager.getIcon(IconManager.java:51)
	at webServer.DirectoryHandler.handleRequest(DirectoryHandler.java:95)
	at webServer.RequestHandlerThread.run(RequestHandlerThread.java:72)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package webServer;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.filechooser.FileSystemView;

public class IconManager {

// put a path that is invalid for your system
	private static final String ICONS_PATH = "/I_dont_exist/icons/";
	
	HashMap<String, String> _iconHash;

	FileSystemView _fileSystem;

	public IconManager() {
		_iconHash = new HashMap<String, String>();
		_fileSystem = FileSystemView.getFileSystemView();
	}

	// this is what i wanted to use to create the directory structure, as you wil
// see below
	public void createCacheDir(String base) {
		File iconsDir = new File (base + ICONS_PATH);
		// Check if 'cache' dir exists
		try {
		if (!iconsDir.isDirectory()){
			iconsDir.mkdirs();
		}
		} catch (Exception e){
			System.err.println("Can't create directory structure for icons.");
		}
		
	}
	// server base string should be a valid path on your system, like: "c:\temp"
// the file is a valid File object to one of your files in a readable folder
// i expect to find on the ICONS_PATH the icon for the file's type, if it's not
// there it calls storeIcon to create the
	public String getIcon(File file, String serverBase) {
		String fileType = _fileSystem.getSystemTypeDescription(file);
		String iconName = ICONS_PATH + fileType + ".png";
		iconName = iconName.replace(" ", "_");
		File iconFile = new File(serverBase + iconName);
		if (iconFile.exists()) {
			if (!_iconHash.containsKey(fileType)){
				_iconHash.put(fileType, iconName);
			}
			return _iconHash.get(fileType);
		} else {
			return storeIcon(file, iconFile, iconName, fileType, serverBase);
		}
	}

// this is what I EXPECT to work, but the exception is never caught here
	public String storeIcon(File file, File iconFile, String iconName,
			String fileType, String serverBase) {
		ImageIcon icon;
		icon = (ImageIcon) _fileSystem.getSystemIcon(file);
		
		// We really need to create the image
		try {
			// Print the icon into the file and save it.
			BufferedImage buff = (BufferedImage) icon.getImage();
			ImageIO.write(buff, "png", iconFile);
		} catch (FileNotFoundException fnfe) {
			System.err.println("Somehow the icons directory can't be found");
			// Recreate the directory
			createCacheDir(serverBase);
			// Recall this method again
			return storeIcon(file, iconFile, iconName, fileType, serverBase);
		} catch (IOException ioe) {
			System.err.println("Somehow the file can't be found");
			return "";
		}
		synchronized (_iconHash) {
			_iconHash.put(fileType, iconName);
			_iconHash.notify();
		}
		return iconName;

	}

}
// that's all.good luck
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
I can't do anything because the exception CAN'T BE CAUGHT.

Comments
Bug 5034864 reports the same problem.
07-05-2014

Please re-open if - if fix is in progress or on the plan to fix soon - if this is a P3 (file as P3, not P4)
18-03-2014

EVALUATION This is a duplicate of 5034864 which mentions both issues here 1) printStackTrace() should not be called 2) Its questionable whether we should be swallowing exceptions. That bug also notes that the docs don't mention the possibility of a "null" return. Since the method already declares it throws IOException it might be possible to wrap whatever exception is thrown (if its not already an IOException) and document one is thrown in this case but there's a lot of fall out from that. Other methods up stream, eg : javax.imageio.ImageIO.createImageOutputStream() *do* document null can be returned, and also throw exceptions which assume that an IOException is solely due to a problem creating a cache file. They would need to be respecified too. So all the cases which use this, and also createInputStreamInstance() would need to be fixed up for consistency. Maybe its best to just add docs to mention that null means the stream could not be created.
23-05-2007