JDK-4407042 : SimpleDateFormat clone() decendents corrupt each other
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.text
  • Affected Version: 1.1.7,1.2.2,1.3.0
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic,windows_nt
  • CPU: generic,x86
  • Submitted: 2001-01-23
  • Updated: 2014-10-30
  • Resolved: 2001-02-27
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.
Other
1.4.0 betaFixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Description

Name: boT120536			Date: 01/22/2001


java version "1.2.2"
Classic VM (build JDK-1.2.2-W, native threads, symcjit)



I have a static instance of SimpleDateFormat, and I have 2 threads, each
using private clones of this instance.  One thread uses the parse() method to
convert a String to a Date, the other uses the format method to convert a Date
to a String.  Even though each thread has a clone of the SimpleDateFormat
instance, the results of the parse and/or format are corrupted after a few
seconds due to apparent concurrent conflicts.  The following code demonstrates
the problem:

import java.io.*;
import java.text.*;
import java.util.*;

public class SDFClone {

    static boolean stopped_ = false;
    static final String TIME_STRING = "2000/11/18 00:01:00";
    static final String TIME_STRING_FULL = "11/18/2000 00:01:00 PST";
    static final long UTC_LONG = 974534460000L;
    static SimpleDateFormat sdf_ = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

    public SDFClone(String[] args) {
        stopped_ = false;
        DateParseThread d1 = new DateParseThread();
        DateFormatThread d2 = new DateFormatThread();
        d1.start();
        d2.start();
        try { Thread.sleep(100000); } catch (Exception e) {}
        stopped_ = true;
    }

    class DateParseThread extends Thread {
        public  void run () {
            SimpleDateFormat sdf = (SimpleDateFormat)SDFClone.sdf_.clone();
            
            try {
                int i = 0;
                while (! SDFClone.stopped_) {
                    Date date =sdf.parse(SDFClone.TIME_STRING);
                    long t = date.getTime();
                    i++;
                    if (t != SDFClone.UTC_LONG ) {
                        throw new ParseException("Error: " + i + " (" +sdf.format(date) + ") " + t + " != " + SDFClone.UTC_LONG, 0);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                System.exit(1);
            }
        }
    }
    class DateFormatThread extends Thread {
        public  void run () {
            SimpleDateFormat sdf = (SimpleDateFormat)SDFClone.sdf_.clone();
            int i = 0;
            while (! SDFClone.stopped_) {
                i++;
                String s = sdf.format(new Date(974534460000L));
                if (!s.equals(SDFClone.TIME_STRING)) {
                    System.err.println("Date Error: " + i + " " + s + " != " +SDFClone.TIME_STRING_FULL);
                    System.exit(1);
                }
            }
        }
    }

    public static void main (String[] args) {
        new SDFClone(args);
    }
}

This defect caused corruption in parsed input dates in an accounting product.
The result was that incorrect resource usage was attributed to users - very bad
for an accounting product!!!
(Review ID: 115583) 
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: merlin-beta FIXED IN: merlin-beta INTEGRATED IN: merlin-beta
14-06-2004

WORK AROUND Name: boT120536 Date: 01/22/2001 Use new instances of the SimpleDateFormat instead of clones. Note: I have had failures while concurrently constructing SimpleDateFormat objects, which is why I tried the clones. The concurrent constructor failure (something about resource bundles) is harder to reproduce...bug report coming. ======================================================================
11-06-2004

EVALUATION While parsing the string, DecimalFormat returns a wrong value. For example, 0 is returned with "2000". This is because internal field DecimalFormat.digitList is not cloned in DecimalFormat.clone(). (DigitList needs to implement clone().) The resource bundle bug mentioned in Workaround was fixed in 1.3. masayoshi.okutsu@Eng 2001-01-23
23-01-2001