Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2067194 | 5.0 | Mark Reinhold | P3 | Resolved | Fixed | b26 |
JDK-2067193 | 1.4.2_05 | Mark Reinhold | P3 | Resolved | Fixed | 05 |
On Multi-processor environment (linux), the attached sample code(A.java)
outputs the attached exception strace.
TEST PROGRAM:
==== A.java ===
public class A {
public static void main(String arg[]) throws Exception {
Thread t1 = new Test();
Thread t2 = new Test();
t1.start();
t2.start();
}
static class Test extends Thread {
public void run() {
while (!interrupted()) {
try {
"a".getBytes("ASCII");
"a".getBytes("EUC-JP-LINUX");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
===============
LOG DATA:
==== log ===
java.lang.Error: java.nio.charset.UnsupportedCharsetException: EUC-JP-LINUX
at java.lang.StringCoding.lookupCharset(StringCoding.java:84)
at java.lang.StringCoding.encode(StringCoding.java:361)
at java.lang.StringCoding.encode(StringCoding.java:378)
at java.lang.String.getBytes(String.java:608)
at java.io.UnixFileSystem.canonicalize(Native Method)
at java.io.File.getCanonicalPath(File.java:513)
at java.io.FilePermission$1.run(FilePermission.java:209)
at java.security.AccessController.doPrivileged(Native Method)
at java.io.FilePermission.init(FilePermission.java:203)
at java.io.FilePermission.<init>(FilePermission.java:253)
at sun.net.www.protocol.file.FileURLConnection.getPermission(FileURLConn
ection.java:193)
at sun.net.www.protocol.jar.JarFileFactory.getPermission(JarFileFactory.
java:111)
at sun.net.www.protocol.jar.JarFileFactory.getCachedJarFile(JarFileFacto
ry.java:81)
at sun.net.www.protocol.jar.JarFileFactory.get(JarFileFactory.java:50)
at sun.net.www.protocol.jar.JarURLConnection.connect(JarURLConnection.ja
va:85)
at sun.net.www.protocol.jar.JarURLConnection.getInputStream(JarURLConnec
tion.java:105)
at java.net.URL.openStream(URL.java:960)
at sun.misc.Service.parse(Service.java:203)
at sun.misc.Service.access$100(Service.java:111)
at sun.misc.Service$LazyIterator.hasNext(Service.java:257)
at java.nio.charset.Charset$1.getNext(Charset.java:301)
at java.nio.charset.Charset$1.hasNext(Charset.java:316)
at java.nio.charset.Charset$2.run(Charset.java:359)
at java.security.AccessController.doPrivileged(Native Method)
at java.nio.charset.Charset.lookupViaProviders(Charset.java:356)
at java.nio.charset.Charset.lookup(Charset.java:383)
at java.nio.charset.Charset.isSupported(Charset.java:405)
at java.lang.StringCoding.lookupCharset(StringCoding.java:80)
at java.lang.StringCoding.encode(StringCoding.java:361)
at java.lang.String.getBytes(String.java:591)
at A$Test.run(A.java:27)
Caused by: java.nio.charset.UnsupportedCharsetException: EUC-JP-LINUX
at java.nio.charset.Charset.forName(Charset.java:428)
at java.lang.StringCoding.lookupCharset(StringCoding.java:82)
... 30 more
============
CONFIGRATION:
- MPU: Pentium III 800MHz X 2
- OS : Turbo Linux 8 (kernel 2.4.18-5smp)
- JRE: JDK1.4.1_01, 1.4.2(b15)
REPORT:
They suspect this is caused when several threads tried to modify the cache
in Charset.
Specifically speaking, java.nio.Charset#isSupported and java.nio.Charset#forName
should be atomic, but they are not.
The followings are the possible senario. Thread-A, B are created in the
test program.
Thread-A Cache Thread-B
-------- ------- ---------
ASCII
(1)
(2)
EUC-JP-LINUX
(3)
(4)
ASCII
(5)
(1) In thread-A, "a".getBytes("EUC-JP-LINUX") runs as follows.
"a".getBytes("EUC-JP-LINUX")
-> StringCoding#lookupCharset
-> Charset#isSupported("EUC-JP-LINUX")
-> Charset#lookup("EUC-JP-LINUX")
At this stage, Charset.cache is "ASCII", cache-miss occurs and
calls Charset#lookupViaProviders.
(2) A sequence of "a".getBytes("EUC-JP-LINUX") finishes in threda-B.
Here, Cache is set to "EUC-JP-LINUX".
(3) During the execution in (1), StringCoding#lookupCharset is called.
(This is from the information in the above log.)
In lookupCharset, Charset#isSupported("EUC-JP-LINUX") is called again
and returns true because of cahce-hit (cahche is set to "EUC-JP-LINUX"
at (2))
(4) A sequence of "a".getBytes("ASCII") finishes.
Here, Cache is set to "ASCII".
(5) Charset#forName("EUC-JP-LINUX") is called after
Charset#isSupported("EUC-JP-LINUX") at (3).
Here, cache-miss occurs and Charset#lookupViaProviders is called.
However, lookupViaProviders is not re-entrant and returns null.
As the result, UnsupportedCharsetException seems to happen.
===========================================================================
- backported by
-
JDK-2067193 (cs) Default charsets must be hardwired
- Resolved
-
JDK-2067194 (cs) Default charsets must be hardwired
- Resolved
- duplicates
-
JDK-5033591 I18N - different behavior when reading invalid char in different locale
- Closed
-
JDK-5031167 NLS: CONVERTING BYTE ARRAY TO STRING USING EUC_CN CHARSET IS NOT CONSISTENT
- Closed
-
JDK-5036209 ByteToCharGB18030 exception in 1.4.2_04-b05
- Closed
- relates to
-
JDK-5080151 (cs) 1.4.2_0X: IllegalStateException: recursive invocation on non-english locales
- Closed
-
JDK-4954023 missing/dropped character in zh_CN.GB18030 locale
- Closed