text: Products and Services
  Downloads
  Store
  Support
  Education
  Partners
  About
  Oracle Technology Network
  Just to make this concrete, here's a small program demonstrating the
  problem. Compile and run it, first against 1.4.2, then against
  1.5/5.0:
  import java.sql.Timestamp;
  import java.util.Date;
  public class Foo {
  public static void main(String[] args) {
  Date d = new Date();
  Timestamp ts = new Timestamp(d.getTime());
  System.out.println(ts.compareTo(d));
  }
  }
  Note that this a *binary compatibility problem*!! The overload
  resolution is the same in 1.4.2 and 1.5.0; in either case, it's
  compareTo(Date). With a 1.4.2 runtime, it dispatches to the version
  defined in java.util.Date, with a 1.5.0 runtime it dispatches to the
  version defined in java.sql.Timestamp, which promptly casts its
  argument to Timestamp (and blows up). This really feels like a P2 bug
  to me.
  EVALUATION
  Fix integrated in jdk 5.0u7 as of Jan 3. This should be available in the builds of jdk5.0u7 after Jan 3.
  EVALUATION
  This is getting fixed in Mustang and jdk5 update release as well.
  I have got the approval and this fix should be in soon.
  All those requesting for this fix watch out for this fix and comeback with your comments.
  SUGGESTED FIX
  public int compareTo(java.util.Date d) {
  if (d instanceof Timestamp)
  return compareTo((Timestamp)d);
  else
  return - (d.compareTo(this));
  }
  ###@###.### 2005-06-07 19:02:25 GMT
  EVALUATION
  A very interesting bug... here's what I think happened.
  In the fix for 4227983 (java.sql.Timestamp didn't overload compareTo, setTime
  and getTime, delta 1.35, 2000/02/02, integrated into 1.4.0), two compareTo
  methods were added to the Timestamp class, one taking a Timestamp and the other
  taking an Object. The compareTo(Object) method was specified as follows:
  * Compares this Timestamp to another Object. If the Object is
  * a Date, this function behaves like compareTo(Timestamp).
  * Otherwise, it throws aClassCastException (as Timestamps are
  * comparable only to other Timestamps)
  * ...
  The intent of this change was to allow Timestamps to be compared to Dates.
  A later fix, for 4631234 (java.sql.Timestamp.compareTo no longer accepts
  java.util.Dates in 1.4, delta 1.46 2002/04/01, integrated into 1.4.1), revised
  the specification of the compareTo(Object) method instead to say:
  * Compares this <code>Timestamp</code> object to the given
  * <code>Object</code>, which must be a <code>Timestamp</code>
  * object. If the argument is not a <code>Timestamp</code> object,
  * this method throws a <code>ClassCastException</code> object.
  * (<code>Timestamp</code> objects are
  * comparable only to other <code>Timestamp</code> objects.)
  In other words, the intent of this change was to require a ClassCastException
  to be thrown when comparing a Timestamp to a Date. Such behavior would cause
  the submitter's code to fail.
  The change for 4631234 did not modify any code. It appears to have been made
  under the assumption that the existing code already behaved according to the
  new specification. Due to the presence of a compareTo(Date) method in the Date
  superclass, however, such comparisons were actually allowed, and so the
  submitter's code actually worked... until recently.
  The generification changes for Tiger (4964490) added the compareTo(Date) method
  to Timestamp in order to preserve what was assumed (from the specification) to
  be the current behavior; unfortunately the fact that the current behavior was
  different from the specified behavior was not noticed at that time. That new
  method is what is now causing the submitter's code to receive the (specified)
  ClassCastException.
  A reasonable fix for this bug would be to revise the specification of the
  Timestamp.compareTo(Date) method to allow Timestamp to be comparable to Dates
  once again, and to redefine that method as
  public int compareTo(java.util.Date d) {
  return d.compareTo(this);
  }
  (Of course the real problem here is that java.sql.Timestamp should not have
  been made a subclass of java.util.Date in the first place, as explained in item
  7 of Bloch's "Effective Java", but that's water under the bridge.)
  -- ###@###.### 2004/9/16
  I agree with the above comprehensive assesment, and I'll work with the JCK team
  and 1.5.x team to get fix for this. A specific determination as to the most
  ideal delivery vehicle still has to be determined, but likely Mustang at this
  point.
  ###@###.### 2004-09-16
  I am looking into fixing this bug.
  The following lines will be getting removed from javadocs for the method
  public int compareTo(java.util.Date o)
  * @exception ClassCastException if the argument is not a
  * <code>Timestamp</code> object
  * @since 1.5
  */
  // This forwarding method ensures that the compareTo(Date) method defined
  // in java.util.Date is not invoked on a Timestamp
  ###@###.### 2005-05-02 05:25:12 GMT
  1. I will be removing the above lines from mustang i.e. jdk 6.0 and will not be doing the changes in jdk5.0uX versions.
  I hope that is fine.
  ###@###.### 2005-06-07 13:58:51 GMT
  2. Also will change the method code to, in addition to above :-
  public int compareTo(java.util.Date d) {
  return - (d.compareTo(this));
  }
  ###@###.### 2005-06-07 14:39:59 GMT
  Since this is a regression and a binary incompatibility,
  it is not unlikely that we will get requests for backports.
  So I think a backport to a Tiger update must be considered.
  The proposed solution is problematic:
  java.util.Date d1 = new java.sql.Timestamp(...);
  java.util.Date d2 = new java.sql.Timestamp(...);
  d1.compareTo(d2); // stack overflow
  See "Suggested Fix" section for an alternative solution.
  ###@###.### 2005-06-07 19:02:25 GMT
  I propose the following fix, other fixes propose either don't work with 1.4.x and 1.5.x or if they work don't produce the same results.
  Index: src/java/sql/Timestamp.java
  (cvs diff -wu Timestamp.java)
  ===================================================================
  RCS file: /m/jws/jdbc4.0/src/java/sql/Timestamp.java,v
  retrieving revision 1.5
  diff -w -u -r1.5 Timestamp.java
  --- src/java/sql/Timestamp.java 18 Jul 2005 19:33:37 -0000 1.5
  +++ src/java/sql/Timestamp.java 21 Jul 2005 11:13:21 -0000
  @@ -462,14 +462,22 @@
  * <code>Timestamp</code> object
  * @since 1.5
  */
  - // This forwarding method ensures that the compareTo(Date) method defined
  - // in java.util.Date is not invoked on a Timestamp
  public int compareTo(java.util.Date o) {
  - return compareTo((Timestamp)o);
  - }
  + if(o instanceof Timestamp) {
  + // When Timestamp instance compare it with a Timestamp
  + // Hence it is basically calling this.compareTo((Timestamp))o);
  + // Note typecasting is safe because o is instance of Timestamp
  + return compareTo((Timestamp)o);
  + } else {
  + // When Date doing a o.compareTo(this)
  + // will give wrong results.
  + Timestamp ts = new Timestamp(o.getTime());
  + return this.compareTo(ts);
  + }
  + }
  static final long serialVersionUID = 2745179027874758501L;
  The test cases against which I verified the fix are already as given here and as below.
  /////////////// Test Case 1 ///////////////////////
  import java.sql.Timestamp;
  import java.util.Date;
  public class Foo {
  public static void main(String[] args) {
  Date d = new Date();
  Timestamp ts = new Timestamp(d.getTime());
  System.out.println(ts.compareTo(d));
  }
  }
  /////////////// Test Case 2 ///////////////////////
  import java.sql.Timestamp;
  import java.util.Date;
  public class Foo1 {
  public static void main(String[] args) {
  Date d1 = new Date();
  java.util.Date d1 = new java.sql.Timestamp(d.getTime());
  java.util.Date d2 = new java.sql.Timestamp(d.getTime());
  System.out.println("Value is : "+d1.compareTo(d2));
  }
  }
  Except the comments(//This forwarding) which I am not sure can be backported, I think this fix of the code can be backported without problems, if required.
  Please comment for the fix.