Skip to content

Commit 5499d74

Browse files
authored
Move JFR functionality into junit-platform-launcher (#4674)
* Avoid storing JFR events when they are disabled * Only fill JFR events if they're about to be committed * Move JFR event generating listeners into junit-platform-launcher * Make JFR optional * Remove unnecessary concurrency handling Resolves #4579.
1 parent 44a4044 commit 5499d74

31 files changed

+152
-177
lines changed

build.gradle.kts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ val platformProjects by extra(listOf(
2222
projects.junitPlatformConsole,
2323
projects.junitPlatformConsoleStandalone,
2424
projects.junitPlatformEngine,
25-
projects.junitPlatformJfr,
2625
projects.junitPlatformLauncher,
2726
projects.junitPlatformReporting,
2827
projects.junitPlatformSuite,

documentation/documentation.gradle.kts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,6 @@ dependencies {
8181
because("Jimfs is used in src/test/java")
8282
}
8383

84-
if (java.toolchain.implementation.orNull == JvmImplementation.J9) {
85-
testRuntimeOnly(libs.jfrPolyfill) {
86-
because("OpenJ9 does not include JFR")
87-
}
88-
}
89-
9084
standaloneConsoleLauncher(projects.junitPlatformConsoleStandalone)
9185
}
9286

documentation/src/docs/asciidoc/release-notes/release-notes-6.0.0-M1.adoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ repository on GitHub.
4949
`--h` (rather than `-h`) or `-help` (rather than `--help`).
5050
* The `junit-platform-runner` module that provided the JUnit 4 based `JUnitPlatform`
5151
runner has been discontinued.
52+
* The `junit-platform-jfr` module that provided custom Java Flight Recorder (JFR) events
53+
for test discovery and execution has been discontinued. Instead, the functionality is
54+
now available directly in `junit-platform-launcher` without requiring an additional
55+
dependency.
5256
* Support for Maven Surefire/Failsafe versions less than 3.0.0 has been dropped.
5357
* The following deprecated APIs have been removed:
5458
- `ReflectionSupport.loadClass(String)` method

documentation/src/docs/asciidoc/user-guide/appendix.adoc

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,6 @@ Please refer to the corresponding sections for <<running-tests-build-maven-bom,
6565
directory. See <<running-tests-console-launcher>> for details.
6666
`junit-platform-engine`::
6767
Public API for test engines. See <<launcher-api-engines-custom>> for details.
68-
`junit-platform-jfr`::
69-
Provides a `LauncherDiscoveryListener` and `TestExecutionListener` for Java Flight
70-
Recorder events on the JUnit Platform. See <<running-tests-listeners-flight-recorder>>
71-
for details.
7268
`junit-platform-launcher`::
7369
Public API for configuring and launching test plans -- typically used by IDEs and
7470
build tools. See <<launcher-api>> for details.

documentation/src/docs/asciidoc/user-guide/running-tests.adoc

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,9 +1119,7 @@ to a problem.
11191119
In order to record Flight Recorder events generated while running tests, you need to:
11201120

11211121
1. Ensure that you are using either Java 8 Update 262 or higher or Java 11 or later.
1122-
2. Provide the `org.junit.platform.jfr` module (`junit-platform-jfr-{version}.jar`)
1123-
on the class-path or module-path at test runtime.
1124-
3. Start flight recording when launching a test run. Flight Recorder can be started via
1122+
2. Start flight recording when launching a test run. Flight Recorder can be started via
11251123
java command line option:
11261124

11271125
-XX:StartFlightRecording:filename=...

documentation/src/plantuml/component-diagram.puml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ package org.junit.platform {
2020
[junit-platform-commons] as commons
2121
[junit-platform-console] as console
2222
[junit-platform-engine] as engine
23-
[junit-platform-jfr] as jfr
2423
[junit-platform-launcher] as launcher
2524
[junit-platform-reporting] as reporting
2625
[junit-platform-suite] as suite

gradle/libs.versions.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ groovy2-bom = { module = "org.codehaus.groovy:groovy-bom", version = "2.5.23" }
4242
hamcrest = { module = "org.hamcrest:hamcrest", version = "3.0" }
4343
jackson-dataformat-yaml = { module = "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml", version.ref = "jackson" }
4444
jackson-module-kotlin = { module = "com.fasterxml.jackson.module:jackson-module-kotlin", version.ref = "jackson" }
45-
jfrPolyfill = { module = "org.gradle.jfr.polyfill:jfr-polyfill", version = "1.0.2" }
4645
jfrunit = { module = "org.moditect.jfrunit:jfrunit-core", version = "1.0.0.Alpha2" }
4746
jimfs = { module = "com.google.jimfs:jimfs", version = "1.3.0" }
4847
jmh-core = { module = "org.openjdk.jmh:jmh-core", version.ref = "jmh" }

gradle/plugins/common/src/main/kotlin/junitbuild.testing-conventions.gradle.kts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -201,13 +201,9 @@ dependencies {
201201
testImplementation(project(":junit-jupiter"))
202202

203203
testRuntimeOnly(project(":junit-platform-engine"))
204-
testRuntimeOnly(project(":junit-platform-jfr"))
205204
testRuntimeOnly(project(":junit-platform-reporting"))
206205

207206
testRuntimeOnly(bundleFromLibs("log4j"))
208-
testRuntimeOnly(dependencyFromLibs("jfrPolyfill")) {
209-
because("OpenJ9 does not include JFR")
210-
}
211207
testRuntimeOnly(dependencyFromLibs("openTestReporting-events")) {
212208
because("it's required to run tests via IntelliJ which does not consumed the shadowed jar of junit-platform-reporting")
213209
}

junit-platform-commons/src/main/java/module-info.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
org.junit.jupiter.params,
5151
org.junit.platform.console,
5252
org.junit.platform.engine,
53-
org.junit.platform.jfr,
5453
org.junit.platform.launcher,
5554
org.junit.platform.reporting,
5655
org.junit.platform.suite.api,

junit-platform-jfr/junit-platform-jfr.gradle.kts

Lines changed: 0 additions & 23 deletions
This file was deleted.

junit-platform-jfr/src/main/java/module-info.java

Lines changed: 0 additions & 35 deletions
This file was deleted.

junit-platform-jfr/src/main/java/org/junit/platform/jfr/package-info.java

Lines changed: 0 additions & 8 deletions
This file was deleted.

junit-platform-jfr/src/main/resources/META-INF/services/org.junit.platform.launcher.LauncherDiscoveryListener

Lines changed: 0 additions & 1 deletion
This file was deleted.

junit-platform-jfr/src/main/resources/META-INF/services/org.junit.platform.launcher.TestExecutionListener

Lines changed: 0 additions & 1 deletion
This file was deleted.

junit-platform-jfr/src/test/README.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

junit-platform-launcher/src/main/java/module-info.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
requires static transitive org.apiguardian.api;
2727
requires static org.jspecify;
28+
requires static jdk.jfr;
2829

2930
requires transitive java.logging;
3031
requires transitive org.junit.platform.commons;

junit-platform-launcher/src/main/java/org/junit/platform/launcher/core/ClasspathAlignmentChecker.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ class ClasspathAlignmentChecker {
3838
"org.junit.platform.commons", //
3939
"org.junit.platform.console", //
4040
"org.junit.platform.engine", //
41-
"org.junit.platform.jfr", //
4241
"org.junit.platform.launcher", //
4342
"org.junit.platform.reporting", //
4443
"org.junit.platform.suite.api", //

junit-platform-launcher/src/main/java/org/junit/platform/launcher/core/LauncherFactory.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.junit.platform.launcher.LauncherSessionListener;
3636
import org.junit.platform.launcher.PostDiscoveryFilter;
3737
import org.junit.platform.launcher.TestExecutionListener;
38+
import org.junit.platform.launcher.jfr.JfrUtils;
3839

3940
/**
4041
* Factory for creating {@link Launcher} instances by invoking {@link #create()}
@@ -139,6 +140,7 @@ private static DefaultLauncher createDefaultLauncher(LauncherConfig config,
139140
Set<TestEngine> engines = collectTestEngines(config);
140141
List<PostDiscoveryFilter> filters = collectPostDiscoveryFilters(config);
141142
DefaultLauncher launcher = new DefaultLauncher(engines, filters, sessionLevelStore);
143+
JfrUtils.registerListeners(launcher);
142144
registerLauncherDiscoveryListeners(config, launcher);
143145
registerTestExecutionListeners(config, launcher, configurationParameters);
144146

junit-platform-jfr/src/main/java/org/junit/platform/jfr/FlightRecordingDiscoveryListener.java renamed to junit-platform-launcher/src/main/java/org/junit/platform/launcher/jfr/FlightRecordingDiscoveryListener.java

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,12 @@
88
* https://www.eclipse.org/legal/epl-v20.html
99
*/
1010

11-
package org.junit.platform.jfr;
11+
package org.junit.platform.launcher.jfr;
1212

13-
import static java.util.Objects.requireNonNull;
14-
import static org.apiguardian.api.API.Status.STABLE;
13+
import static org.apiguardian.api.API.Status.INTERNAL;
1514

15+
import java.util.HashMap;
1616
import java.util.Map;
17-
import java.util.concurrent.ConcurrentHashMap;
18-
import java.util.concurrent.atomic.AtomicReference;
1917

2018
import jdk.jfr.Category;
2119
import jdk.jfr.Event;
@@ -40,50 +38,62 @@
4038
* @since 1.8
4139
* @see <a href="https://openjdk.java.net/jeps/328">JEP 328: Flight Recorder</a>
4240
*/
43-
@API(status = STABLE, since = "1.11")
44-
public class FlightRecordingDiscoveryListener implements LauncherDiscoveryListener {
41+
@API(status = INTERNAL, since = "6.0")
42+
class FlightRecordingDiscoveryListener implements LauncherDiscoveryListener {
4543

46-
private final AtomicReference<@Nullable LauncherDiscoveryEvent> launcherDiscoveryEvent = new AtomicReference<>();
47-
private final Map<org.junit.platform.engine.UniqueId, EngineDiscoveryEvent> engineDiscoveryEvents = new ConcurrentHashMap<>();
44+
private final Map<org.junit.platform.engine.UniqueId, EngineDiscoveryEvent> engineDiscoveryEvents = new HashMap<>();
45+
private @Nullable LauncherDiscoveryEvent launcherDiscoveryEvent;
4846

4947
@Override
5048
public void launcherDiscoveryStarted(LauncherDiscoveryRequest request) {
51-
LauncherDiscoveryEvent event = new LauncherDiscoveryEvent();
52-
event.selectors = request.getSelectorsByType(DiscoverySelector.class).size();
53-
event.filters = request.getFiltersByType(DiscoveryFilter.class).size();
54-
event.begin();
55-
launcherDiscoveryEvent.set(event);
49+
var event = new LauncherDiscoveryEvent();
50+
if (event.isEnabled()) {
51+
event.begin();
52+
this.launcherDiscoveryEvent = event;
53+
}
5654
}
5755

5856
@Override
5957
public void launcherDiscoveryFinished(LauncherDiscoveryRequest request) {
60-
requireNonNull(launcherDiscoveryEvent.getAndSet(null)).commit();
58+
LauncherDiscoveryEvent event = this.launcherDiscoveryEvent;
59+
this.launcherDiscoveryEvent = null;
60+
if (event != null && event.shouldCommit()) {
61+
event.selectors = request.getSelectorsByType(DiscoverySelector.class).size();
62+
event.filters = request.getFiltersByType(DiscoveryFilter.class).size();
63+
event.commit();
64+
}
6165
}
6266

6367
@Override
6468
public void engineDiscoveryStarted(org.junit.platform.engine.UniqueId engineId) {
65-
EngineDiscoveryEvent event = new EngineDiscoveryEvent();
66-
event.uniqueId = engineId.toString();
67-
event.begin();
68-
engineDiscoveryEvents.put(engineId, event);
69+
var event = new EngineDiscoveryEvent();
70+
if (event.isEnabled()) {
71+
event.begin();
72+
this.engineDiscoveryEvents.put(engineId, event);
73+
}
6974
}
7075

7176
@Override
7277
public void engineDiscoveryFinished(org.junit.platform.engine.UniqueId engineId, EngineDiscoveryResult result) {
73-
EngineDiscoveryEvent event = engineDiscoveryEvents.remove(engineId);
74-
event.result = result.getStatus().toString();
75-
event.commit();
78+
EngineDiscoveryEvent event = this.engineDiscoveryEvents.remove(engineId);
79+
if (event != null && event.shouldCommit()) {
80+
event.uniqueId = engineId.toString();
81+
event.result = result.getStatus().toString();
82+
event.commit();
83+
}
7684
}
7785

7886
@Override
7987
public void issueEncountered(org.junit.platform.engine.UniqueId engineId, DiscoveryIssue issue) {
80-
DiscoveryIssueEvent event = new DiscoveryIssueEvent();
81-
event.engineId = engineId.toString();
82-
event.severity = issue.severity().name();
83-
event.message = issue.message();
84-
event.source = issue.source().map(Object::toString).orElse(null);
85-
event.cause = issue.cause().map(ExceptionUtils::readStackTrace).orElse(null);
86-
event.commit();
88+
var event = new DiscoveryIssueEvent();
89+
if (event.shouldCommit()) {
90+
event.engineId = engineId.toString();
91+
event.severity = issue.severity().name();
92+
event.message = issue.message();
93+
event.source = issue.source().map(Object::toString).orElse(null);
94+
event.cause = issue.cause().map(ExceptionUtils::readStackTrace).orElse(null);
95+
event.commit();
96+
}
8797
}
8898

8999
@Category({ "JUnit", "Discovery" })

0 commit comments

Comments
 (0)