changeset 14783:dc3322ef23ff

8144262: LogRecord.getMillis() method is a convenience API that should not have been deprecated Summary: LogRecord.getMillis() is no longer deprecated. LogRecord.setInstant() check that the instant millis can fit in a long millisecond-since-epoch. Reviewed-by: lancea, rriggs, smarks
author dfuchs
date Mon, 07 Dec 2015 12:35:37 +0100
parents 8a5d5ff42c90
children c021b855f51e a333d6e4f1e9 64dcdca11308
files src/java.logging/share/classes/java/util/logging/LogRecord.java test/java/util/logging/HigherResolutionTimeStamps/LogRecordWithNanosAPI.java
diffstat 2 files changed, 43 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.logging/share/classes/java/util/logging/LogRecord.java	Mon Dec 07 15:48:56 2015 +0800
+++ b/src/java.logging/share/classes/java/util/logging/LogRecord.java	Mon Dec 07 12:35:37 2015 +0100
@@ -468,12 +468,11 @@
      * @implSpec This is equivalent to calling
      *      {@link #getInstant() getInstant().toEpochMilli()}.
      *
-     * @deprecated To get the full nanosecond resolution event time,
+     * @apiNote To get the full nanosecond resolution event time,
      *             use {@link #getInstant()}.
      *
      * @see #getInstant()
      */
-    @Deprecated
     public long getMillis() {
         return instant.toEpochMilli();
     }
@@ -487,8 +486,10 @@
      *      {@link #setInstant(java.time.Instant)
      *      setInstant(Instant.ofEpochMilli(millis))}.
      *
-     * @deprecated To set event time with nanosecond resolution,
-     *             use {@link #setInstant(java.time.Instant)}.
+     * @deprecated LogRecord maintains timestamps with nanosecond resolution,
+     *             using {@link Instant} values. For this reason,
+     *             {@link #setInstant(java.time.Instant) setInstant()}
+     *             should be used in preference to {@code setMillis()}.
      *
      * @see #setInstant(java.time.Instant)
      */
@@ -510,14 +511,23 @@
 
     /**
      * Sets the instant that the event occurred.
+     * <p>
+     * If the given {@code instant} represents a point on the time-line too
+     * far in the future or past to fit in a {@code long} milliseconds and
+     * nanoseconds adjustment, then an {@code ArithmeticException} will be
+     * thrown.
      *
      * @param instant the instant that the event occurred.
      *
      * @throws NullPointerException if {@code instant} is null.
+     * @throws ArithmeticException if numeric overflow would occur while
+     *         calling {@link Instant#toEpochMilli() instant.toEpochMilli()}.
+     *
      * @since 1.9
      */
     public void setInstant(Instant instant) {
-        this.instant = Objects.requireNonNull(instant);
+        instant.toEpochMilli();
+        this.instant = instant;
     }
 
     /**
--- a/test/java/util/logging/HigherResolutionTimeStamps/LogRecordWithNanosAPI.java	Mon Dec 07 15:48:56 2015 +0800
+++ b/test/java/util/logging/HigherResolutionTimeStamps/LogRecordWithNanosAPI.java	Mon Dec 07 12:35:37 2015 +0100
@@ -33,7 +33,7 @@
 
 /**
  * @test
- * @bug 8072645
+ * @bug 8072645 8144262
  * @summary tests the new methods added to LogRecord.
  * @run main LogRecordWithNanosAPI
  * @author danielfuchs
@@ -299,10 +299,37 @@
 
         try {
             record.setInstant(null);
+            throw new RuntimeException("Expected NullPointerException not thrown");
         } catch (NullPointerException x) {
             System.out.println("Got expected NPE when trying to call record.setInstant(null): " + x);
         }
 
+        // This instant is the biggest for which toEpochMilli will not throw...
+        final Instant max = Instant.ofEpochMilli(Long.MAX_VALUE).plusNanos(999_999L);
+        record.setInstant(max);
+        assertEquals(Long.MAX_VALUE / 1000L,
+                     record.getInstant().getEpochSecond(),
+                     "max instant seconds [record.getInstant().getEpochSecond()]");
+        assertEquals(Long.MAX_VALUE,
+                     record.getInstant().toEpochMilli(),
+                     "max instant millis [record.getInstant().toEpochMilli()]");
+        assertEquals(Long.MAX_VALUE, record.getMillis(),
+                     "max instant millis [record.getMillis()]");
+        assertEquals((Long.MAX_VALUE % 1000L)*1000_000L + 999_999L,
+                     record.getInstant().getNano(),
+                     "max instant nanos [record.getInstant().getNano()]");
+
+        // Too big by 1 ns.
+        final Instant tooBig = max.plusNanos(1L);
+        try {
+            record.setInstant(tooBig);
+            throw new RuntimeException("Expected ArithmeticException not thrown");
+        } catch (ArithmeticException x) {
+            System.out.println("Got expected ArithmeticException when trying"
+                    + " to call record.setInstant(Instant.ofEpochMilli(Long.MAX_VALUE)"
+                    + ".plusNanos(999_999L).plusNanos(1L)): " + x);
+        }
+
     }
 
 }