Skip to content

Commit c62cd6a

Browse files
authored
Fix package path computation in ClasspathScanner
Fix `getRootUrisForPackage()` in class `ClasspathScanner` by looking for two "wordings" of a package name. For example, package `foo.bar` is expanded to `foo/bar` and `foo/bar/`. The latter allows find package `foo.bar` in a module called `foo.bar`, and not `foo`. This commit also ensures, that there's no regression (compared to #2531) by launching test runs using the standalone artifact with `--select-package` and `--scan-class-path`. Fixes #2500 Fixes #2600 Fixes #2612
1 parent d597bb5 commit c62cd6a

File tree

3 files changed

+96
-4
lines changed

3 files changed

+96
-4
lines changed

documentation/src/docs/asciidoc/release-notes/release-notes-5.8.0-M2.adoc

+3-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ on GitHub.
1515

1616
==== Bug Fixes
1717

18-
* ❓
18+
* Method `getRootUrisForPackage()` in class `ClasspathScanner` now returns a
19+
valid list of class names when the package name is equal to the name of a
20+
module on the module path and when running on Java 8.
1921

2022
==== Deprecations and Breaking Changes
2123

junit-platform-commons/src/main/java/org/junit/platform/commons/util/ClasspathScanner.java

+25-3
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@
2525
import java.util.ArrayList;
2626
import java.util.Collection;
2727
import java.util.Enumeration;
28+
import java.util.LinkedHashSet;
2829
import java.util.List;
30+
import java.util.Set;
2931
import java.util.function.BiFunction;
3032
import java.util.function.Consumer;
3133
import java.util.function.Supplier;
@@ -50,6 +52,8 @@ class ClasspathScanner {
5052
private static final Logger logger = LoggerFactory.getLogger(ClasspathScanner.class);
5153

5254
private static final char CLASSPATH_RESOURCE_PATH_SEPARATOR = '/';
55+
private static final String CLASSPATH_RESOURCE_PATH_SEPARATOR_STRING = String.valueOf(
56+
CLASSPATH_RESOURCE_PATH_SEPARATOR);
5357
private static final char PACKAGE_SEPARATOR_CHAR = '.';
5458
private static final String PACKAGE_SEPARATOR_STRING = String.valueOf(PACKAGE_SEPARATOR_CHAR);
5559

@@ -76,7 +80,8 @@ List<Class<?>> scanForClassesInPackage(String basePackageName, ClassFilter class
7680
Preconditions.notNull(classFilter, "classFilter must not be null");
7781
basePackageName = basePackageName.trim();
7882

79-
return findClassesForUris(getRootUrisForPackage(basePackageName), basePackageName, classFilter);
83+
return findClassesForUris(getRootUrisForPackageNameOnClassPathAndModulePath(basePackageName), basePackageName,
84+
classFilter);
8085
}
8186

8287
List<Class<?>> scanForClassesInClasspathRoot(URI root, ClassFilter classFilter) {
@@ -212,12 +217,29 @@ private ClassLoader getClassLoader() {
212217
return this.classLoaderSupplier.get();
213218
}
214219

220+
private List<URI> getRootUrisForPackageNameOnClassPathAndModulePath(String basePackageName) {
221+
Set<URI> uriSet = new LinkedHashSet<>(getRootUrisForPackage(basePackageName));
222+
if (!basePackageName.isEmpty() && !basePackageName.endsWith(PACKAGE_SEPARATOR_STRING)) {
223+
getRootUrisForPackage(basePackageName + PACKAGE_SEPARATOR_STRING).stream() //
224+
.map(ClasspathScanner::removeTrailingClasspathResourcePathSeparator) //
225+
.forEach(uriSet::add);
226+
}
227+
return new ArrayList<>(uriSet);
228+
}
229+
230+
private static URI removeTrailingClasspathResourcePathSeparator(URI uri) {
231+
String string = uri.toString();
232+
if (string.endsWith(CLASSPATH_RESOURCE_PATH_SEPARATOR_STRING)) {
233+
return URI.create(string.substring(0, string.length() - 1));
234+
}
235+
return uri;
236+
}
237+
215238
private static String packagePath(String packageName) {
216239
if (packageName.isEmpty()) {
217240
return "";
218241
}
219-
String path = packageName.replace(PACKAGE_SEPARATOR_CHAR, CLASSPATH_RESOURCE_PATH_SEPARATOR);
220-
return path + CLASSPATH_RESOURCE_PATH_SEPARATOR;
242+
return packageName.replace(PACKAGE_SEPARATOR_CHAR, CLASSPATH_RESOURCE_PATH_SEPARATOR);
221243
}
222244

223245
private List<URI> getRootUrisForPackage(String basePackageName) {

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

+68
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.junit.jupiter.api.Order;
3131
import org.junit.jupiter.api.Test;
3232
import org.junit.jupiter.api.TestMethodOrder;
33+
import org.opentest4j.TestAbortedException;
3334

3435
import platform.tooling.support.Helper;
3536
import platform.tooling.support.MavenRepo;
@@ -121,6 +122,73 @@ void test() throws IOException {
121122

122123
@Test
123124
@Order(3)
125+
void testOnJava8() throws IOException {
126+
var result = Request.builder() //
127+
.setTool(new Java()) //
128+
.setJavaHome(Helper.getJavaHome("8").orElseThrow(TestAbortedException::new)) //
129+
.setProject("standalone") //
130+
.addArguments("--show-version") //
131+
.addArguments("-enableassertions") //
132+
.addArguments("-Djava.util.logging.config.file=logging.properties") //
133+
.addArguments("-jar", MavenRepo.jar("junit-platform-console-standalone")) //
134+
.addArguments("--scan-class-path") //
135+
.addArguments("--disable-banner") //
136+
.addArguments("--include-classname", "standalone.*") //
137+
.addArguments("--classpath", "bin").build() //
138+
.run(false);
139+
140+
assertEquals(1, result.getExitCode(), String.join("\n", result.getOutputLines("out")));
141+
142+
var workspace = Request.WORKSPACE.resolve("standalone");
143+
var expectedOutLines = Files.readAllLines(workspace.resolve("expected-out.txt"));
144+
var expectedErrLines = Files.readAllLines(workspace.resolve("expected-err.txt"));
145+
assertLinesMatch(expectedOutLines, result.getOutputLines("out"));
146+
assertLinesMatch(expectedErrLines, result.getOutputLines("err"));
147+
148+
var jupiterVersion = Helper.version("junit-jupiter-engine");
149+
var vintageVersion = Helper.version("junit-vintage-engine");
150+
assertTrue(result.getOutput("err").contains("junit-jupiter"
151+
+ " (group ID: org.junit.jupiter, artifact ID: junit-jupiter-engine, version: " + jupiterVersion));
152+
assertTrue(result.getOutput("err").contains("junit-vintage"
153+
+ " (group ID: org.junit.vintage, artifact ID: junit-vintage-engine, version: " + vintageVersion));
154+
}
155+
156+
@Test
157+
@Order(3)
158+
// https://github.com/junit-team/junit5/issues/2600
159+
void testOnJava8SelectPackage() throws IOException {
160+
var result = Request.builder() //
161+
.setTool(new Java()) //
162+
.setJavaHome(Helper.getJavaHome("8").orElseThrow(TestAbortedException::new)) //
163+
.setProject("standalone") //
164+
.addArguments("--show-version") //
165+
.addArguments("-enableassertions") //
166+
.addArguments("-Djava.util.logging.config.file=logging.properties") //
167+
.addArguments("-jar", MavenRepo.jar("junit-platform-console-standalone")) //
168+
.addArguments("--select-package", "standalone") //
169+
.addArguments("--disable-banner") //
170+
.addArguments("--include-classname", "standalone.*") //
171+
.addArguments("--classpath", "bin").build() //
172+
.run(false);
173+
174+
assertEquals(1, result.getExitCode(), String.join("\n", result.getOutputLines("out")));
175+
176+
var workspace = Request.WORKSPACE.resolve("standalone");
177+
var expectedOutLines = Files.readAllLines(workspace.resolve("expected-out.txt"));
178+
var expectedErrLines = Files.readAllLines(workspace.resolve("expected-err.txt"));
179+
assertLinesMatch(expectedOutLines, result.getOutputLines("out"));
180+
assertLinesMatch(expectedErrLines, result.getOutputLines("err"));
181+
182+
var jupiterVersion = Helper.version("junit-jupiter-engine");
183+
var vintageVersion = Helper.version("junit-vintage-engine");
184+
assertTrue(result.getOutput("err").contains("junit-jupiter"
185+
+ " (group ID: org.junit.jupiter, artifact ID: junit-jupiter-engine, version: " + jupiterVersion));
186+
assertTrue(result.getOutput("err").contains("junit-vintage"
187+
+ " (group ID: org.junit.vintage, artifact ID: junit-vintage-engine, version: " + vintageVersion));
188+
}
189+
190+
@Test
191+
@Order(5)
124192
@Disabled("https://github.com/junit-team/junit5/issues/1724")
125193
void testWithJarredTestClasses() {
126194
var jar = MavenRepo.jar("junit-platform-console-standalone");

0 commit comments

Comments
 (0)