8294242: JFR: jfr print doesn't handle infinite duration well

Reviewed-by: mgronlun
This commit is contained in:
Erik Gahlin 2022-10-04 11:45:53 +00:00
parent 5a9cd33632
commit 4d6668e7ee
4 changed files with 27 additions and 2 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -32,6 +32,8 @@ import java.lang.annotation.Target;
/** /**
* Event field annotation, specifies that the value is a duration. * Event field annotation, specifies that the value is a duration.
* <p>
* If the annotated value equals {@code Long.MAX_VALUE), it represents forever.
* *
* @since 9 * @since 9
*/ */

View File

@ -31,6 +31,7 @@ import java.io.StringWriter;
import java.time.Duration; import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@ -755,6 +756,10 @@ public sealed class RecordedObject
* the following types: {@code long}, {@code int}, {@code short}, {@code char}, * the following types: {@code long}, {@code int}, {@code short}, {@code char},
* and {@code byte}. * and {@code byte}.
* <p> * <p>
* If the committed event value was {@code Long.MAX_VALUE},
* regardless of the unit set by {@code @Timespan}, this method returns
* {@link ChronoUnit.FOREVER.getDuration()}.
* <p>
* It's possible to index into a nested object using {@code "."} (for example, * It's possible to index into a nested object using {@code "."} (for example,
* {@code "aaa.bbb"}). * {@code "aaa.bbb"}).
* <p> * <p>
@ -811,6 +816,9 @@ public sealed class RecordedObject
if (timespan == Long.MIN_VALUE) { if (timespan == Long.MIN_VALUE) {
return Duration.ofSeconds(Long.MIN_VALUE, 0); return Duration.ofSeconds(Long.MIN_VALUE, 0);
} }
if (timespan == Long.MAX_VALUE) {
return ChronoUnit.FOREVER.getDuration();
}
Timespan ts = v.getAnnotation(Timespan.class); Timespan ts = v.getAnnotation(Timespan.class);
if (ts != null) { if (ts != null) {
switch (ts.value()) { switch (ts.value()) {

View File

@ -29,6 +29,7 @@ import java.io.PrintWriter;
import java.time.Duration; import java.time.Duration;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.StringJoiner; import java.util.StringJoiner;
@ -553,6 +554,10 @@ public final class PrettyWriter extends EventPrintWriter {
println("N/A"); println("N/A");
return true; return true;
} }
if (d.equals(ChronoUnit.FOREVER.getDuration())) {
println("Forever");
return true;
}
println(Utils.formatDuration(d)); println(Utils.formatDuration(d));
return true; return true;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,6 +26,7 @@ package jdk.jfr.api.consumer;
import java.io.IOException; import java.io.IOException;
import java.time.Duration; import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -92,6 +93,12 @@ public class TestRecordedObject {
@Timespan(Timespan.SECONDS) @Timespan(Timespan.SECONDS)
long durationSeconds = DURATION_VALUE.toSeconds(); long durationSeconds = DURATION_VALUE.toSeconds();
@Timespan(Timespan.SECONDS)
long foreverMillis = Long.MAX_VALUE;
@Timespan(Timespan.NANOSECONDS)
long foreverNanoseconds = Long.MAX_VALUE;
@Timestamp(Timestamp.MILLISECONDS_SINCE_EPOCH) @Timestamp(Timestamp.MILLISECONDS_SINCE_EPOCH)
long instantMillis = 1000; long instantMillis = 1000;
@ -179,6 +186,9 @@ public class TestRecordedObject {
Asserts.assertEquals(event.getDuration("durationMicros"), DURATION_VALUE); Asserts.assertEquals(event.getDuration("durationMicros"), DURATION_VALUE);
Asserts.assertEquals(event.getDuration("durationMillis"), DURATION_VALUE); Asserts.assertEquals(event.getDuration("durationMillis"), DURATION_VALUE);
Asserts.assertEquals(event.getDuration("durationSeconds"), DURATION_VALUE); Asserts.assertEquals(event.getDuration("durationSeconds"), DURATION_VALUE);
Asserts.assertEquals(event.getDuration("foreverMillis"), ChronoUnit.FOREVER.getDuration());
Asserts.assertEquals(event.getDuration("foreverNanoseconds"), ChronoUnit.FOREVER.getDuration());
Asserts.assertEquals(event.getInstant("instantMillis").toEpochMilli(), 1000L); Asserts.assertEquals(event.getInstant("instantMillis").toEpochMilli(), 1000L);
if (!event.getInstant("instantTicks").isBefore(INSTANT_VALUE)) { if (!event.getInstant("instantTicks").isBefore(INSTANT_VALUE)) {
throw new AssertionError("Expected start time of JVM to before call to Instant.now()"); throw new AssertionError("Expected start time of JVM to before call to Instant.now()");