JDK-8230767 : FlightRecorderListener returns null recording
  • Type: Bug
  • Component: hotspot
  • Sub-Component: jfr
  • Affected Version: 11,14
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2019-09-09
  • Updated: 2020-11-26
  • Resolved: 2019-11-11
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.
JDK 11 JDK 13 JDK 14
11.0.9-oracleFixed 13.0.6Fixed 14 b23Fixed
Description
The jdk.jfr.FlightRecorderListener allows clients to listens to changes to JFR, such as when a new recording is started and stopped. For example, 

FlightRecorder.addListener(new FlightRecorderListener() {
  public void recordingStateChanged(Recording r) {
    System.out.println("Recording " + r.getName() + " " + r.getState());
  }
});

This works well, but if a user calls Recording::dump(path):

Recording r = new Recording();
r.dump(Path.of("dump.jfr"));

the JFR implementation piggybacks on the existing implementation and creates a temporary cloned recording in the dump method that is not visible to users. The temporary recording holds references to chunks in the disk repository while the dump takes places. This is so chunks are not removed by some other mechanism, for example maxAge and maxSize, while the dump happens.

Problem is that a notification is sent for the internal/temporary recording and since there is no jdk.jfr.Recording object associated with it, it returns null. Fix is to not send a notification if it is an internal recording

The problem is manifested as a NullPointerException in the code that is using FlightRecorder::addListener method.
Comments
Fix Request (13u) Requesting backport to 13u for parity with 11u. The original patch applies cleanly and fixes the problem. Tested with tier1 and jdk/jfr. The added test fails without the patch and passes with it.
11-11-2020

Fix Request (11u): Patch applied cleanly. Tier one tests and jfr tests ran without issue. Reproducer failed before, and passed after, the patch was applied. The problem is actually minimal as the exception is otherwise caught and logged as a warning, though the fix is also equally minimal. I wonder what other opinions are on backporting this to 11.
22-05-2020

I was able to see this issue on 11 $ java11 -version openjdk version "11.0.7" 2020-04-14 OpenJDK Runtime Environment 18.9 (build 11.0.7+10) OpenJDK 64-Bit Server VM 18.9 (build 11.0.7+10, mixed mode, sharing) with the following test code: {code} import jdk.jfr.FlightRecorder; import jdk.jfr.FlightRecorderListener; import jdk.jfr.Recording; import java.nio.file.Path; public class Main { public static void main(String[] args) throws Exception { FlightRecorder.addListener(new FlightRecorderListener() { public void recordingStateChanged(Recording r) { try { System.out.println("Recording " + r.getName() + " " + r.getState()); } catch (Exception e) { e.printStackTrace(); } } }); Recording r = new Recording(); r.start(); r.dump(Path.of("dump.jfr")); r.stop(); r.close(); } } {code}
22-05-2020

URL: https://hg.openjdk.java.net/jdk/jdk/rev/d4cae08239f7 User: egahlin Date: 2019-11-11 13:49:13 +0000
11-11-2019

ILW = MMM = P3
10-09-2019