JDK-4954004 : Convert use of old sun.io APIs into new java.nio.charset APIs
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 6
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2003-11-13
  • Updated: 2005-02-28
  • Resolved: 2005-02-28
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 6
6 b26Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
In Mustang, we plan to remove sun.io.  The contents of this internal API have
been deprecated in favor of java.nio.charset which was introduced in Merlin.
As of Tiger, the old sun.io converters redirect to the new API.  Use of
the old converters will result in a deprecation warning at compile time.

The following list of files from the j2se workspace have been identified as
depending on sun.io:

  src/share/classes/sun/awt/datatransfer/DataTransferer.java

These files (and any others which use sun.io) need to be converted to use the
new java.nio APIs in Dragonfly so that sun.io can be deleted in an early
promotion of Mustang.

-- iag@sfbay 2003-11-13

Comments
SUGGESTED FIX *** /net/titan/export1/gas/mustang/webrev/src/share/classes/sun/awt/datatransfer/DataTransferer.java- Mon Feb 21 14:37:30 2005 --- DataTransferer.java Mon Feb 21 13:30:19 2005 -------------------------------------------------------------------------------- *** 30,40 **** import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Reader; import java.io.SequenceInputStream; import java.io.StringReader; - import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; --- 30,39 ---- -------------------------------------------------------------------------------- *** 91,106 **** import javax.imageio.stream.ImageOutputStream; import sun.awt.image.ImageRepresentation; import sun.awt.image.ToolkitImage; - // TODO - // - // Remove import - import sun.io.CharToByteConverter; - /** * Provides a set of functions to be shared among the DataFlavor class and * platform-specific data transfer implementations. * * The concept of "flavors" and "natives" is extended to include "formats", --- 90,100 ---- -------------------------------------------------------------------------------- *** 157,175 **** public static final DataFlavor javaTextEncodingFlavor; private static SortedSet standardEncodings; /** - * Encodings that we know are or are not supported go in this Map. It's - * much faster than actually encoding some text. - */ - // TODO - // - // Eliminate this field in conjunction with isEncodingSupported(String) - private static final Map knownEncodings; - - /** * Tracks whether a particular text/* MIME type supports the charset * parameter. The Map is initialized with all of the standard MIME types * listed in the DataFlavor.selectBestTextFlavor method comment. Additional * entries may be added during the life of the JRE for text/<other> types. */ --- 151,160 ---- -------------------------------------------------------------------------------- *** 242,264 **** ("application/x-java-text-encoding;class=\"[B\""); } catch (ClassNotFoundException cannotHappen) { } javaTextEncodingFlavor = tJavaTextEncodingFlavor; ! // TODO ! // ! // Eliminate this code in conjunction with isEncodingSupported(String) ! Map tempMap = new HashMap(11); ! tempMap.put("ASCII", Boolean.TRUE); // US-ASCII ! tempMap.put("ISO8859_1", Boolean.TRUE); // ISO-8859-1 ! tempMap.put("UTF8", Boolean.TRUE); // UTF-8 ! tempMap.put("UnicodeBigUnmarked", Boolean.TRUE); // UTF-16BE ! tempMap.put("UnicodeLittleUnmarked", Boolean.TRUE); // UTF-16LE ! tempMap.put("UTF16", Boolean.TRUE); // UTF-16 ! knownEncodings = Collections.synchronizedMap(tempMap); ! ! tempMap = new HashMap(17); tempMap.put("sgml", Boolean.TRUE); tempMap.put("xml", Boolean.TRUE); tempMap.put("html", Boolean.TRUE); tempMap.put("enriched", Boolean.TRUE); tempMap.put("richtext", Boolean.TRUE); --- 227,237 ---- ("application/x-java-text-encoding;class=\"[B\""); } catch (ClassNotFoundException cannotHappen) { } javaTextEncodingFlavor = tJavaTextEncodingFlavor; ! Map tempMap = new HashMap(17); tempMap.put("sgml", Boolean.TRUE); tempMap.put("xml", Boolean.TRUE); tempMap.put("html", Boolean.TRUE); tempMap.put("enriched", Boolean.TRUE); tempMap.put("richtext", Boolean.TRUE); -------------------------------------------------------------------------------- *** 348,369 **** */ public static String canonicalName(String encoding) { if (encoding == null) { return null; } ! ! // TODO ! // ! // Don't use java.nio API until alias list is equivalent to ! // CharacterEncoding.aliasName(String). ! // ! // String canonicalName = Charset.forName(encoding).toString(); ! String canonicalName = sun.io.CharacterEncoding.aliasName(encoding); ! if (canonicalName == null) { ! canonicalName = encoding; } - return canonicalName; } /** * If the specified flavor is a text flavor which supports the "charset" * parameter, then this method returns that parameter, or the default --- 321,337 ---- */ public static String canonicalName(String encoding) { if (encoding == null) { return null; } ! try { ! return Charset.forName(encoding).name(); ! } catch (IllegalCharsetNameException icne) { ! return encoding; ! } catch (UnsupportedCharsetException uce) { ! return encoding; } } /** * If the specified flavor is a text flavor which supports the "charset" * parameter, then this method returns that parameter, or the default -------------------------------------------------------------------------------- *** 380,413 **** return (encoding != null) ? encoding : getDefaultTextCharset(); } /** ! * Returns the platform's default character encoding. This code is ! * based on code available in sun.io.Converters.getDefaultConverterClass. */ public static String getDefaultTextCharset() { if (defaultEncoding != null) { return defaultEncoding; } ! ! PrivilegedAction a = ! new sun.security.action.GetPropertyAction("file.encoding"); ! String enc = (String)AccessController.doPrivileged(a); ! if (enc != null) { ! defaultEncoding = DataTransferer.canonicalName(enc); ! if (!isEncodingSupported(defaultEncoding)) { ! // ISO8859_1 is a canonical encoding ! defaultEncoding = "ISO8859_1"; } - return defaultEncoding; - } else { - /* Property not yet set, so do not set default encoding and - just use ISO8859_1 for now */ - return "ISO8859_1"; // ISO8859_1 is a canonical encoding - } - } /** * Tests only whether the flavor's MIME type supports the charset * parameter. Must only be called for flavors with a primary type of * "text". --- 348,365 ---- return (encoding != null) ? encoding : getDefaultTextCharset(); } /** ! * Returns the platform's default character encoding. */ public static String getDefaultTextCharset() { if (defaultEncoding != null) { return defaultEncoding; } ! return defaultEncoding = Charset.defaultCharset().name(); } /** * Tests only whether the flavor's MIME type supports the charset * parameter. Must only be called for flavors with a primary type of * "text". -------------------------------------------------------------------------------- *** 509,545 **** /** * Determines whether this JRE can both encode and decode text in the * specified encoding. */ - // TODO - // - // Eliminate this method and replace with calls to - // Charset.isSupported(String) public static boolean isEncodingSupported(String encoding) { if (encoding == null) { return false; } - String canonicalName = DataTransferer.canonicalName(encoding); - - Boolean bool = (Boolean)knownEncodings.get(canonicalName); - - if (bool == null) { - // keep looking - try to encode something and see if io complains try { ! new String("abc".getBytes(canonicalName), canonicalName); ! bool = Boolean.TRUE; ! } catch (UnsupportedEncodingException encodingException) { ! bool = Boolean.FALSE; } - - knownEncodings.put(canonicalName, bool); } - return (bool == Boolean.TRUE); - } - /** * Returns an Iterator which traverses a SortedSet of Strings which are * a total order of the standard character sets supported by the JRE. The * ordering follows the same principles as DataFlavor.selectBestTextFlavor. * So as to avoid loading all available character converters, optional, --- 461,481 ---- /** * Determines whether this JRE can both encode and decode text in the * specified encoding. */ public static boolean isEncodingSupported(String encoding) { if (encoding == null) { return false; } try { ! return Charset.isSupported(encoding); ! } catch (IllegalCharsetNameException icne) { ! return false; } } /** * Returns an Iterator which traverses a SortedSet of Strings which are * a total order of the standard character sets supported by the JRE. The * ordering follows the same principles as DataFlavor.selectBestTextFlavor. * So as to avoid loading all available character converters, optional, -------------------------------------------------------------------------------- *** 1654,1664 **** * Used for decoding and reencoding an InputStream on demand so that we * can strip NUL terminators and perform EOLN search-and-replace. */ public class ReencodingInputStream extends InputStream { protected BufferedReader wrapped; - protected CharToByteConverter converter; // TODO remove protected final char[] in = new char[1]; protected byte[] out; protected CharsetEncoder encoder; protected CharBuffer inBuf; --- 1590,1599 ---- -------------------------------------------------------------------------------- *** 1698,1727 **** sourceEncoding = getDefaultTextCharset(); } wrapped = new BufferedReader (new InputStreamReader(bytestream, sourceEncoding)); ! // TODO ! // ! // Remove converter. Use encoder only. try { - converter = CharToByteConverter.getConverter(targetEncoding); - out = new byte[converter.getMaxBytesPerChar()]; - } catch (UnsupportedEncodingException e) { - try { encoder = Charset.forName(targetEncoding).newEncoder(); out = new byte[(int)(encoder.maxBytesPerChar() + 0.5)]; inBuf = CharBuffer.wrap(in); outBuf = ByteBuffer.wrap(out); ! } catch (IllegalCharsetNameException ee) { ! throw e; ! } catch (UnsupportedCharsetException ee) { ! throw e; ! } catch (UnsupportedOperationException ee) { ! throw e; } - } String sEoln = (String)nativeEOLNs.get(lFormat); if (sEoln != null) { eoln = sEoln.toCharArray(); } --- 1633,1662 ---- sourceEncoding = getDefaultTextCharset(); } wrapped = new BufferedReader (new InputStreamReader(bytestream, sourceEncoding)); ! if (targetEncoding == null) { ! // Throw NullPointerException for compatibility with the former ! // call to sun.io.CharToByteConverter.getConverter(null) ! // (Charset.forName(null) throws unspecified IllegalArgumentException ! // now; see 6228568) ! throw new NullPointerException("null target encoding"); ! } ! try { encoder = Charset.forName(targetEncoding).newEncoder(); out = new byte[(int)(encoder.maxBytesPerChar() + 0.5)]; inBuf = CharBuffer.wrap(in); outBuf = ByteBuffer.wrap(out); ! } catch (IllegalCharsetNameException e) { ! throw new IOException(e.toString()); ! } catch (UnsupportedCharsetException e) { ! throw new IOException(e.toString()); ! } catch (UnsupportedOperationException e) { ! throw new IOException(e.toString()); } String sEoln = (String)nativeEOLNs.get(lFormat); if (sEoln != null) { eoln = sEoln.toCharArray(); } -------------------------------------------------------------------------------- *** 1755,1775 **** c = '\n' & 0xFFFF; } in[0] = (char)c; - // TODO - // - // Remove converter. Use encoder only. - if (converter != null) { - limit = converter.convert(in, 0, 1, out, 0, out.length); - } else /* if (encoder != null) */ { inBuf.rewind(); outBuf.rewind(); encoder.encode(inBuf, outBuf, false); limit = outBuf.limit(); - } index = 0; return read(); } else { --- 1690,1704 ---- c = '\n' & 0xFFFF; } in[0] = (char)c; inBuf.rewind(); outBuf.rewind(); encoder.encode(inBuf, outBuf, false); + outBuf.flip(); limit = outBuf.limit(); index = 0; return read(); } else { -------------------------------------------------------------------------------- *** 2352,2365 **** static { HashMap charsetsMap = new HashMap(8, 1.0f); // we prefer Unicode charsets - // - // TODO - // - // Canonical names will change when we switch to java.nio charsetsMap.put("Unicode", Integer.valueOf(3)); charsetsMap.put("UnicodeLittleUnmarked", Integer.valueOf(4)); charsetsMap.put("UnicodeBigUnmarked", Integer.valueOf(5)); charsetsMap.put("UTF8", Integer.valueOf(6)); charsetsMap.put("UTF16", Integer.valueOf(7)); --- 2281,2290 ---- ###@###.### 2005-2-24 11:38:51 GMT
24-02-2005

EVALUATION Name: dsR10078 Date: 11/15/2003 Will be fixed in dragon. ###@###.### 2003-11-14 ====================================================================== The datatransfer system uses sun.io converters in a couple of ways: 1) implicitly, via String(byte[] bytes, String charsetName), String.getBytes(String charsetName), InputStreamReader(InputStream in, String charsetName) and 2) it uses sun.io.CharToByteConverter explicitly for converting native EOLs in some cases. Explicit usage of sun.io should be removed. Also DataTransferer utility methods related to encodings should be rewritten using nio API. A great attention should be drawn to compatibility issues. For safe switching from sun.io converters to nio converters the statement must be true: for every encoding name ENC if there exists the corresponding sun.io converter, then Charset.isSupported(ENC) returns true. I should mention the encoding name "unicode" particularly, since its lack in nio causes a failure of a simple datatransfer test. Datatransfer code uses the "unicode" encoding name, it's even mentioned in the javadoc for java.awt.datatransfer.DataFlavor.plainTextFlavor. The encoding name "unicode" should be added to the UTF-16 alias list. Also the following bugs were filed: 6176819 Translate sun.io COMPOUND_TEXT converters to NIO 6228568 (cs) Charset.forName() throws inaccurate/inappropriate exception when null is the charset name. ###@###.### 2005-2-24 11:38:51 GMT
24-02-2005

CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: mustang
17-09-2004