Skip to content

Commit 9b90b24

Browse files
sormurasmarcphilipp
authored andcommitted
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 7c1a995 commit 9b90b24

6 files changed

Lines changed: 66 additions & 52 deletions

File tree

documentation/modules/ROOT/partials/release-notes/release-notes-5.14.2.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ repository on GitHub.
1616
[[v5.14.2-junit-platform-bug-fixes]]
1717
==== Bug Fixes
1818

19-
*
19+
* Make `ConsoleLauncher` compatible with JDK 26 by avoiding final field mutations.
2020

2121
[[v5.14.2-junit-platform-deprecations-and-breaking-changes]]
2222
==== Deprecations and Breaking Changes

junit-platform-console/src/main/java/org/junit/platform/console/command/MainCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class MainCommand implements Callable<Object>, IExitCodeGenerator {
6161
AnsiColorOptionMixin ansiColorOption;
6262

6363
@Unmatched
64-
private final List<String> allParameters = new ArrayList<>();
64+
private List<String> allParameters = new ArrayList<>();
6565

6666
@Spec
6767
CommandSpec commandSpec;

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

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

4949
@Option(names = "-details", hidden = true, defaultValue = DEFAULT_DETAILS_NAME)
50-
private final Details details2 = DEFAULT_DETAILS;
50+
private Details details2 = DEFAULT_DETAILS;
5151

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

5656
@Option(names = "-details-theme", hidden = true)
57-
private final Theme theme2 = DEFAULT_THEME;
57+
private Theme theme2 = DEFAULT_THEME;
5858

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

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

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -75,91 +75,91 @@ public static class SelectorOptions {
7575

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

8080
@Option(names = { "--u",
8181
"-select-uri" }, arity = "1..*", hidden = true, converter = SelectorConverter.Uri.class)
82-
private final List<UriSelector> selectedUris2 = new ArrayList<>();
82+
private List<UriSelector> selectedUris2 = new ArrayList<>();
8383

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

9191
@Option(names = { "--f",
9292
"-select-file" }, arity = "1..*", hidden = true, converter = SelectorConverter.File.class)
93-
private final List<FileSelector> selectedFiles2 = new ArrayList<>();
93+
private List<FileSelector> selectedFiles2 = new ArrayList<>();
9494

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

9999
@Option(names = { "--d",
100100
"-select-directory" }, arity = "1..*", hidden = true, converter = SelectorConverter.Directory.class)
101-
private final List<DirectorySelector> selectedDirectories2 = new ArrayList<>();
101+
private List<DirectorySelector> selectedDirectories2 = new ArrayList<>();
102102

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

107107
@Option(names = { "--o",
108108
"-select-module" }, arity = "1..*", converter = SelectorConverter.Module.class, hidden = true)
109-
private final List<ModuleSelector> selectedModules2 = new ArrayList<>();
109+
private List<ModuleSelector> selectedModules2 = new ArrayList<>();
110110

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

115115
@Option(names = { "--p",
116116
"-select-package" }, arity = "1..*", hidden = true, converter = SelectorConverter.Package.class)
117-
private final List<PackageSelector> selectedPackages2 = new ArrayList<>();
117+
private List<PackageSelector> selectedPackages2 = new ArrayList<>();
118118

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

123123
@Option(names = { "--c",
124124
"-select-class" }, arity = "1..*", hidden = true, converter = SelectorConverter.Class.class)
125-
private final List<ClassSelector> selectedClasses2 = new ArrayList<>();
125+
private List<ClassSelector> selectedClasses2 = new ArrayList<>();
126126

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

131131
@Option(names = { "--m",
132132
"-select-method" }, arity = "1..*", hidden = true, converter = SelectorConverter.Method.class)
133-
private final List<MethodSelector> selectedMethods2 = new ArrayList<>();
133+
private List<MethodSelector> selectedMethods2 = new ArrayList<>();
134134

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

139139
@Option(names = { "--r",
140140
"-select-resource" }, arity = "1..*", hidden = true, converter = SelectorConverter.ClasspathResource.class)
141-
private final List<ClasspathResourceSelector> selectedClasspathResources2 = new ArrayList<>();
141+
private List<ClasspathResourceSelector> selectedClasspathResources2 = new ArrayList<>();
142142

143143
@Option(names = { "-i",
144144
"--select-iteration" }, paramLabel = "PREFIX:VALUE[INDEX(..INDEX)?(,INDEX(..INDEX)?)*]", arity = "1..*", converter = SelectorConverter.Iteration.class, //
145145
description = "Select iterations for test discovery via a prefixed identifier and a list of indexes or index ranges "
146146
+ "(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). "
147147
+ "This option can be repeated.")
148-
private final List<IterationSelector> selectedIterations = new ArrayList<>();
148+
private List<IterationSelector> selectedIterations = new ArrayList<>();
149149

150150
@Option(names = { "--i",
151151
"-select-iteration" }, arity = "1..*", hidden = true, converter = SelectorConverter.Iteration.class)
152-
private final List<IterationSelector> selectedIterations2 = new ArrayList<>();
152+
private List<IterationSelector> selectedIterations2 = new ArrayList<>();
153153

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

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

164164
SelectorOptions() {
165165
}
@@ -191,74 +191,74 @@ public static class FilterOptions {
191191
+ "names that begin with \"Test\" or end with \"Test\" or \"Tests\". " //
192192
+ "When this option is repeated, all patterns will be combined using OR semantics. " //
193193
+ "Default: ${DEFAULT-VALUE}")
194-
private final List<String> includeClassNamePatterns = new ArrayList<>();
194+
private List<String> includeClassNamePatterns = new ArrayList<>();
195195

196196
@Option(names = { "--n", "-include-classname" }, arity = "1", hidden = true)
197-
private final List<String> includeClassNamePatterns2 = new ArrayList<>();
197+
private List<String> includeClassNamePatterns2 = new ArrayList<>();
198198

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

204204
@Option(names = { "--N", "-exclude-classname" }, arity = "1", hidden = true)
205-
private final List<String> excludeClassNamePatterns2 = new ArrayList<>();
205+
private List<String> excludeClassNamePatterns2 = new ArrayList<>();
206206

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

211211
@Option(names = { "-include-package" }, arity = "1", hidden = true)
212-
private final List<String> includePackages2 = new ArrayList<>();
212+
private List<String> includePackages2 = new ArrayList<>();
213213

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

218218
@Option(names = { "-exclude-package" }, arity = "1", hidden = true)
219-
private final List<String> excludePackages2 = new ArrayList<>();
219+
private List<String> excludePackages2 = new ArrayList<>();
220220

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

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

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

237237
@Option(names = { "--t", "-include-tag" }, arity = "1", hidden = true)
238-
private final List<String> includedTags2 = new ArrayList<>();
238+
private List<String> includedTags2 = new ArrayList<>();
239239

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

246246
@Option(names = { "--T", "-exclude-tag" }, arity = "1", hidden = true)
247-
private final List<String> excludedTags2 = new ArrayList<>();
247+
private List<String> excludedTags2 = new ArrayList<>();
248248

249249
@Option(names = { "-e",
250250
"--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.")
251-
private final List<String> includedEngines = new ArrayList<>();
251+
private List<String> includedEngines = new ArrayList<>();
252252

253253
@Option(names = { "--e", "-include-engine" }, arity = "1", hidden = true)
254-
private final List<String> includedEngines2 = new ArrayList<>();
254+
private List<String> includedEngines2 = new ArrayList<>();
255255

256256
@Option(names = { "-E",
257257
"--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.")
258-
private final List<String> excludedEngines = new ArrayList<>();
258+
private List<String> excludedEngines = new ArrayList<>();
259259

260260
@Option(names = { "--E", "-exclude-engine" }, arity = "1", hidden = true)
261-
private final List<String> excludedEngines2 = new ArrayList<>();
261+
private List<String> excludedEngines2 = new ArrayList<>();
262262

263263
private void applyTo(TestDiscoveryOptions result) {
264264
result.setIncludedClassNamePatterns(merge(this.includeClassNamePatterns, this.includeClassNamePatterns2));
@@ -279,14 +279,14 @@ public static class RuntimeConfigurationOptions {
279279
@Option(names = { "-" + CP_OPTION, "--classpath",
280280
"--class-path" }, converter = ClasspathEntriesConverter.class, paramLabel = "PATH", arity = "1", description = "Provide additional classpath entries "
281281
+ "-- for example, for adding engines and their dependencies. This option can be repeated.")
282-
private final List<Path> additionalClasspathEntries = new ArrayList<>();
282+
private List<Path> additionalClasspathEntries = new ArrayList<>();
283283

284284
@Option(names = { "--cp", "-classpath",
285285
"-class-path" }, converter = ClasspathEntriesConverter.class, hidden = true)
286-
private final List<Path> additionalClasspathEntries2 = new ArrayList<>();
286+
private List<Path> additionalClasspathEntries2 = new ArrayList<>();
287287

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

291291
@Option(names = {
292292
"--config-resource" }, paramLabel = "PATH", arity = "1", description = "Set configuration parameters for test discovery and execution via a classpath resource. This option can be repeated.")

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)