Skip to content

Commit 0d1d359

Browse files
authored
Avoid mutating final fields
Avoid mutating final fields by either removing the `final` modifier from options-related field in the console configuration helper classes and, for the time being, enabling final field mutation in Maven-based integration tests.
1 parent eefea05 commit 0d1d359

File tree

7 files changed

+113
-34
lines changed

7 files changed

+113
-34
lines changed

documentation/src/docs/asciidoc/release-notes/index.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ include::{basedir}/release-notes-6.1.0-M2.adoc[]
2121

2222
include::{basedir}/release-notes-6.1.0-M1.adoc[]
2323

24+
include::{basedir}/release-notes-6.0.2.adoc[]
25+
2426
include::{basedir}/release-notes-6.0.1.adoc[]
2527

2628
include::{basedir}/release-notes-6.0.0.adoc[]
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
[[release-notes-6.0.2]]
2+
== 6.0.2
3+
4+
*Date of Release:* ❓
5+
6+
*Scope:* ❓
7+
8+
For a complete list of all _closed_ issues and pull requests for this release, consult the
9+
link:{junit-framework-repo}+/milestone/113?closed=1+[6.0.2] milestone page in the JUnit
10+
repository on GitHub.
11+
12+
13+
[[release-notes-6.0.2-junit-platform]]
14+
=== JUnit Platform
15+
16+
[[release-notes-6.0.2-junit-platform-bug-fixes]]
17+
==== Bug Fixes
18+
19+
* Make `ConsoleLauncher` compatible with JDK 26 by avoiding final field mutations.
20+
21+
[[release-notes-6.0.2-junit-platform-deprecations-and-breaking-changes]]
22+
==== Deprecations and Breaking Changes
23+
24+
* ❓
25+
26+
[[release-notes-6.0.2-junit-platform-new-features-and-improvements]]
27+
==== New Features and Improvements
28+
29+
* ❓
30+
31+
32+
[[release-notes-6.0.2-junit-jupiter]]
33+
=== JUnit Jupiter
34+
35+
[[release-notes-6.0.2-junit-jupiter-bug-fixes]]
36+
==== Bug Fixes
37+
38+
* ❓
39+
40+
[[release-notes-6.0.2-junit-jupiter-deprecations-and-breaking-changes]]
41+
==== Deprecations and Breaking Changes
42+
43+
* ❓
44+
45+
[[release-notes-6.0.2-junit-jupiter-new-features-and-improvements]]
46+
==== New Features and Improvements
47+
48+
* ❓
49+
50+
51+
[[release-notes-6.0.2-junit-vintage]]
52+
=== JUnit Vintage
53+
54+
[[release-notes-6.0.2-junit-vintage-bug-fixes]]
55+
==== Bug Fixes
56+
57+
* ❓
58+
59+
[[release-notes-6.0.2-junit-vintage-deprecations-and-breaking-changes]]
60+
==== Deprecations and Breaking Changes
61+
62+
* ❓
63+
64+
[[release-notes-6.0.2-junit-vintage-new-features-and-improvements]]
65+
==== New Features and Improvements
66+
67+
* ❓

junit-platform-console/src/main/java/org/junit/platform/console/options/TestConsoleOutputOptionsMixin.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@ public static class ConsoleOutputOptions {
4141
@Option(names = "--details", paramLabel = "MODE", defaultValue = DEFAULT_DETAILS_NAME, description = "Select an output details mode for when tests are executed. " //
4242
+ "Use one of: ${COMPLETION-CANDIDATES}. If 'none' is selected, " //
4343
+ "then only the summary and test failures are shown. Default: ${DEFAULT-VALUE}.")
44-
private final Details details = DEFAULT_DETAILS;
44+
private Details details = DEFAULT_DETAILS;
4545

4646
@Option(names = "--details-theme", paramLabel = "THEME", description = "Select an output details tree theme for when tests are executed. "
4747
+ "Use one of: ${COMPLETION-CANDIDATES}. Default is detected based on default character encoding.")
48-
private final Theme theme = DEFAULT_THEME;
48+
private Theme theme = DEFAULT_THEME;
4949

5050
@Option(names = "--redirect-stdout", paramLabel = "FILE", description = "Redirect test output to stdout to a file.")
5151
private @Nullable Path stdout;

junit-platform-console/src/main/java/org/junit/platform/console/options/TestDiscoveryOptionsMixin.java

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -68,55 +68,55 @@ public static class SelectorOptions {
6868

6969
@Option(names = { "-u",
7070
"--select-uri" }, paramLabel = "URI", arity = "1..*", converter = SelectorConverter.Uri.class, description = "Select a URI for test discovery. This option can be repeated.")
71-
private final List<UriSelector> selectedUris = new ArrayList<>();
71+
private List<UriSelector> selectedUris = new ArrayList<>();
7272

7373
@Option(names = { "-f",
7474
"--select-file" }, paramLabel = "FILE", arity = "1..*", converter = SelectorConverter.File.class, //
7575
description = "Select a file for test discovery. "
7676
+ "The line and column numbers can be provided as URI query parameters (e.g. foo.txt?line=12&column=34). "
7777
+ "This option can be repeated.")
78-
private final List<FileSelector> selectedFiles = new ArrayList<>();
78+
private List<FileSelector> selectedFiles = new ArrayList<>();
7979

8080
@Option(names = { "-d",
8181
"--select-directory" }, paramLabel = "DIR", arity = "1..*", converter = SelectorConverter.Directory.class, description = "Select a directory for test discovery. This option can be repeated.")
82-
private final List<DirectorySelector> selectedDirectories = new ArrayList<>();
82+
private List<DirectorySelector> selectedDirectories = new ArrayList<>();
8383

8484
@Option(names = { "-o",
8585
"--select-module" }, paramLabel = "NAME", arity = "1..*", converter = SelectorConverter.Module.class, description = "Select single module for test discovery. This option can be repeated.")
86-
private final List<ModuleSelector> selectedModules = new ArrayList<>();
86+
private List<ModuleSelector> selectedModules = new ArrayList<>();
8787

8888
@Option(names = { "-p",
8989
"--select-package" }, paramLabel = "PKG", arity = "1..*", converter = SelectorConverter.Package.class, description = "Select a package for test discovery. This option can be repeated.")
90-
private final List<PackageSelector> selectedPackages = new ArrayList<>();
90+
private List<PackageSelector> selectedPackages = new ArrayList<>();
9191

9292
@Option(names = { "-c",
9393
"--select-class" }, paramLabel = "CLASS", arity = "1..*", converter = SelectorConverter.Class.class, description = "Select a class for test discovery. This option can be repeated.")
94-
private final List<ClassSelector> selectedClasses = new ArrayList<>();
94+
private List<ClassSelector> selectedClasses = new ArrayList<>();
9595

9696
@Option(names = { "-m",
9797
"--select-method" }, paramLabel = "NAME", arity = "1..*", converter = SelectorConverter.Method.class, description = "Select a method for test discovery. This option can be repeated.")
98-
private final List<MethodSelector> selectedMethods = new ArrayList<>();
98+
private List<MethodSelector> selectedMethods = new ArrayList<>();
9999

100100
@Option(names = { "-r",
101101
"--select-resource" }, paramLabel = "RESOURCE", arity = "1..*", converter = SelectorConverter.ClasspathResource.class, description = "Select a classpath resource for test discovery. This option can be repeated.")
102-
private final List<ClasspathResourceSelector> selectedClasspathResources = new ArrayList<>();
102+
private List<ClasspathResourceSelector> selectedClasspathResources = new ArrayList<>();
103103

104104
@Option(names = { "-i",
105105
"--select-iteration" }, paramLabel = "PREFIX:VALUE[INDEX(..INDEX)?(,INDEX(..INDEX)?)*]", arity = "1..*", converter = SelectorConverter.Iteration.class, //
106106
description = "Select iterations for test discovery via a prefixed identifier and a list of indexes or index ranges "
107107
+ "(e.g. method:com.acme.Foo#m()[1..2] selects the first and second iteration of the m() method in the com.acme.Foo class). "
108108
+ "This option can be repeated.")
109-
private final List<IterationSelector> selectedIterations = new ArrayList<>();
109+
private List<IterationSelector> selectedIterations = new ArrayList<>();
110110

111111
@Option(names = { "--select-unique-id",
112112
"--uid" }, paramLabel = "UNIQUE-ID", arity = "1..*", converter = SelectorConverter.UniqueId.class, //
113113
description = "Select a unique id for test discovery. This option can be repeated.")
114-
private final List<UniqueIdSelector> selectedUniqueIds = new ArrayList<>();
114+
private List<UniqueIdSelector> selectedUniqueIds = new ArrayList<>();
115115

116116
@Option(names = "--select", paramLabel = "PREFIX:VALUE", arity = "1..*", converter = SelectorConverter.Identifier.class, //
117117
description = "Select via a prefixed identifier (e.g. method:com.acme.Foo#m selects the m() method in the com.acme.Foo class). "
118118
+ "This option can be repeated.")
119-
private final List<DiscoverySelectorIdentifier> selectorIdentifiers = new ArrayList<>();
119+
private List<DiscoverySelectorIdentifier> selectorIdentifiers = new ArrayList<>();
120120

121121
SelectorOptions() {
122122
}
@@ -147,46 +147,46 @@ public static class FilterOptions {
147147
+ "names that begin with \"Test\" or end with \"Test\" or \"Tests\". " //
148148
+ "When this option is repeated, all patterns will be combined using OR semantics. " //
149149
+ "Default: ${DEFAULT-VALUE}")
150-
private final List<String> includeClassNamePatterns = new ArrayList<>();
150+
private List<String> includeClassNamePatterns = new ArrayList<>();
151151

152152
@Option(names = { "-N",
153153
"--exclude-classname" }, paramLabel = "PATTERN", arity = "1", description = "Provide a regular expression to exclude those classes whose fully qualified names match. " //
154154
+ "When this option is repeated, all patterns will be combined using OR semantics.")
155-
private final List<String> excludeClassNamePatterns = new ArrayList<>();
155+
private List<String> excludeClassNamePatterns = new ArrayList<>();
156156

157157
@Option(names = "--include-package", paramLabel = "PKG", arity = "1", description = "?Provide a package to be included in the test run. This option can be repeated.")
158-
private final List<String> includePackages = new ArrayList<>();
158+
private List<String> includePackages = new ArrayList<>();
159159

160160
@Option(names = "--exclude-package", paramLabel = "PKG", arity = "1", description = "Provide a package to be excluded from the test run. This option can be repeated.")
161-
private final List<String> excludePackages = new ArrayList<>();
161+
private List<String> excludePackages = new ArrayList<>();
162162

163163
@Option(names = "--include-methodname", paramLabel = "PATTERN", arity = "1", description = "Provide a regular expression to include only methods whose fully qualified names without parameters match. " //
164164
+ "When this option is repeated, all patterns will be combined using OR semantics.")
165-
private final List<String> includeMethodNamePatterns = new ArrayList<>();
165+
private List<String> includeMethodNamePatterns = new ArrayList<>();
166166

167167
@Option(names = "--exclude-methodname", paramLabel = "PATTERN", arity = "1", description = "Provide a regular expression to exclude those methods whose fully qualified names without parameters match. " //
168168
+ "When this option is repeated, all patterns will be combined using OR semantics.")
169-
private final List<String> excludeMethodNamePatterns = new ArrayList<>();
169+
private List<String> excludeMethodNamePatterns = new ArrayList<>();
170170

171171
@Option(names = { "-t",
172172
"--include-tag" }, paramLabel = "TAG", arity = "1", description = "Provide a tag or tag expression to include only tests whose tags match. "
173173
+ //
174174
"When this option is repeated, all patterns will be combined using OR semantics.")
175-
private final List<String> includedTags = new ArrayList<>();
175+
private List<String> includedTags = new ArrayList<>();
176176

177177
@Option(names = { "-T",
178178
"--exclude-tag" }, paramLabel = "TAG", arity = "1", description = "Provide a tag or tag expression to exclude those tests whose tags match. "
179179
+ //
180180
"When this option is repeated, all patterns will be combined using OR semantics.")
181-
private final List<String> excludedTags = new ArrayList<>();
181+
private List<String> excludedTags = new ArrayList<>();
182182

183183
@Option(names = { "-e",
184184
"--include-engine" }, paramLabel = "ID", arity = "1", description = "Provide the ID of an engine to be included in the test run. This option can be repeated.")
185-
private final List<String> includedEngines = new ArrayList<>();
185+
private List<String> includedEngines = new ArrayList<>();
186186

187187
@Option(names = { "-E",
188188
"--exclude-engine" }, paramLabel = "ID", arity = "1", description = "Provide the ID of an engine to be excluded from the test run. This option can be repeated.")
189-
private final List<String> excludedEngines = new ArrayList<>();
189+
private List<String> excludedEngines = new ArrayList<>();
190190

191191
private void applyTo(TestDiscoveryOptions result) {
192192
result.setIncludedClassNamePatterns(this.includeClassNamePatterns);
@@ -207,10 +207,10 @@ public static class RuntimeConfigurationOptions {
207207
@Option(names = { "-" + CP_OPTION, "--classpath",
208208
"--class-path" }, converter = ClasspathEntriesConverter.class, paramLabel = "PATH", arity = "1", description = "Provide additional classpath entries "
209209
+ "-- for example, for adding engines and their dependencies. This option can be repeated.")
210-
private final List<Path> additionalClasspathEntries = new ArrayList<>();
210+
private List<Path> additionalClasspathEntries = new ArrayList<>();
211211

212212
// Implementation note: the @Option annotation is on a setter method to allow validation.
213-
private final Map<String, String> configurationParameters = new LinkedHashMap<>();
213+
private Map<String, String> configurationParameters = new LinkedHashMap<>();
214214

215215
@Option(names = "--config-resource", paramLabel = "PATH", arity = "1", description = "Set configuration parameters for test discovery and execution via a classpath resource. This option can be repeated.")
216216
private List<String> configurationParametersResources = new ArrayList<>();

platform-tooling-support-tests/src/main/java/platform/tooling/support/ProcessStarters.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,6 @@ public static ProcessStarter gradlew() {
5050
.addArguments("-PjunitVersion=" + Helper.version());
5151
}
5252

53-
public static ProcessStarter maven() {
54-
return maven(currentJdkHome());
55-
}
56-
5753
public static ProcessStarter maven(Path javaHome) {
5854
return new ProcessStarter() //
5955
.executable(Path.of(System.getProperty("mavenDistribution")).resolve("bin").resolve(

platform-tooling-support-tests/src/test/java/platform/tooling/support/tests/MavenEnvVars.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,33 @@
1010

1111
package platform.tooling.support.tests;
1212

13+
import java.util.ArrayList;
14+
import java.util.List;
1315
import java.util.Map;
1416

1517
import org.junit.jupiter.api.condition.JRE;
1618

1719
final class MavenEnvVars {
1820

19-
private static final Map<String, String> FOR_JDK24_AND_LATER = Map.of("MAVEN_OPTS", String.join(" ", //
21+
private static final List<String> FOR_JDK24_AND_LATER = List.of( //
2022
"--enable-native-access=ALL-UNNAMED", // https://issues.apache.org/jira/browse/MNG-8248
2123
"--sun-misc-unsafe-memory-access=allow" // https://issues.apache.org/jira/browse/MNG-8399
22-
));
24+
);
25+
private static final List<String> FOR_JDK26_AND_LATER = List.of( //
26+
"--enable-final-field-mutation=ALL-UNNAMED" // https://github.com/junit-team/junit-framework/issues/5173
27+
);
2328

2429
static Map<String, String> forJre(JRE jre) {
25-
return jre.compareTo(JRE.JAVA_24) >= 0 ? FOR_JDK24_AND_LATER : Map.of();
30+
var list = new ArrayList<String>();
31+
if (jre.compareTo(JRE.JAVA_24) >= 0)
32+
list.addAll(FOR_JDK24_AND_LATER);
33+
if (jre.compareTo(JRE.JAVA_26) >= 0) {
34+
// exclude "leyden" and "valhalla" builds
35+
if (Runtime.version().build().orElse(0) >= 25) {
36+
list.addAll(FOR_JDK26_AND_LATER);
37+
}
38+
}
39+
return list.isEmpty() ? Map.of() : Map.of("MAVEN_OPTS", String.join(" ", list));
2640
}
2741

2842
private MavenEnvVars() {

platform-tooling-support-tests/src/test/java/platform/tooling/support/tests/UnalignedClasspathTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ void verifyErrorMessageForUnalignedClasspath(JRE jre, Path javaHome, @TempDir Pa
5151
.workingDir(copyToWorkspace(Projects.JUPITER_STARTER, workspace)) //
5252
.addArguments(localMavenRepo.toCliArgument(), "-Dmaven.repo=" + MavenRepo.dir()) //
5353
.addArguments("-Dsnapshot.repo.url=" + mavenRepoProxy.getBaseUri()) //
54-
.addArguments("-Djunit.platform.commons.version=1.11.4").addArguments("--update-snapshots",
55-
"--batch-mode", "verify") //
54+
.addArguments("-Djunit.platform.commons.version=1.11.4") //
55+
.addArguments("--update-snapshots", "--batch-mode", "verify") //
5656
.putEnvironment(MavenEnvVars.forJre(jre)) //
5757
.redirectOutput(outputFiles);
5858
var result = starter.startAndWait();

0 commit comments

Comments
 (0)