Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6915656

Charset.aliases() not thread-safe due to possible data-reordering

XMLWordPrintable

      FULL PRODUCT VERSION :
      java version "1.6.0_17"
      Java(TM) SE Runtime Environment (build 1.6.0_17-b04)
      Java HotSpot(TM) 64-Bit Server VM (build 14.3-b01, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Linux tonks 2.6.31-gentoo-r8 #1 SMP PREEMPT Sat Dec 19 13:46:51 CET 2009 x86_64 AMD Athlon(tm) X2 Dual Core Processor BE-2350 AuthenticAMD GNU/Linux

      A DESCRIPTION OF THE PROBLEM :
      The javadoc of Charset claims that the class is thread-safe, but there seems to be a problem with the lazy-caching of the "aliasSet".
      The Java Memory model defines that unsynchronized concurrent accesses to non-volatile fields can be reordered, which may result in Charset.aliases() returning "null" instead of a Set. See the chapter on reordering in the jsr133-FAQ for technical details.

      This can be fixed by reading the field only once, so that there is nothing to be reordered. String.hashCode() is an example how to do it right.


      REPRODUCIBILITY :
      This bug can be reproduced always.

      CUSTOMER SUBMITTED WORKAROUND :
      possible Patch (dedicated to the public domain)

      diff -r c028d78fa438 src/share/classes/java/nio/charset/Charset.java
      --- a/src/share/classes/java/nio/charset/Charset.java Tue Jan 05 10:40:44 2010 +0800
      +++ b/src/share/classes/java/nio/charset/Charset.java Tue Jan 05 20:56:41 2010 +0100
      @@ -666,13 +666,14 @@
            * @return An immutable set of this charset's aliases
            */
           public final Set<String> aliases() {
      - if (aliasSet != null)
      - return aliasSet;
      + Set<String> s = aliasSet;
      + if (s != null)
      + return s;
               int n = aliases.length;
               HashSet<String> hs = new HashSet<String>(n);
               for (int i = 0; i < n; i++)
                   hs.add(aliases[i]);
      - aliasSet = Collections.unmodifiableSet(hs);
      + aliasSet = s = Collections.unmodifiableSet(hs);
               return aliasSet;
           }

            igerasim Ivan Gerasimov
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: