Skip to content

Commit 142476c

Browse files
committed
Polish contribution
See #1987, #2107
1 parent c12634c commit 142476c

File tree

8 files changed

+79
-50
lines changed

8 files changed

+79
-50
lines changed

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ repository on GitHub.
3232
which return a `Stream`.
3333
* New `tryToLoadClass(...)` variant in `ReflectionSupport` that accepts an explicit
3434
`ClassLoader`, allowing classes to be resolved with custom `ClassLoader` arrangements.
35-
* New overloaded constructors for `ClassSelector` and `MethodSelector` that take an
36-
explicit `ClassLoader` as a parameter, allowing selectors to select classes in custom
37-
`ClassLoader` arrangements like in OSGi.
3835
* `ReflectionSupport.findMethod(Class<?>, String, String)` now uses the `ClassLoader` of
3936
the supplied `Class` to load parameter types instead of using the _default_
4037
`ClassLoader`. This allows parameter types to be resolved with custom `ClassLoader`
4138
arrangements (such as OSGi). Consequently, `DiscoverySelectors.selectMethod(Class<?>,
4239
String, String)` also now works properly with custom `ClassLoader` arrangements.
40+
* New overloaded constructors for `ClassSelector` and `MethodSelector` that take an
41+
explicit `ClassLoader` as a parameter, allowing selectors to select classes in custom
42+
`ClassLoader` arrangements like in OSGi.
4343
* For consistency with JUnit Jupiter lifecycle callbacks, listener method pairs for
4444
started/finished and opened/closed events are now invoked using "wrapping" semantics.
4545
This means that finished/closed event methods are invoked in reverse order compared to

junit-platform-engine/src/main/java/org/junit/platform/engine/discovery/ClassSelector.java

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
package org.junit.platform.engine.discovery;
1212

13+
import static org.apiguardian.api.API.Status.EXPERIMENTAL;
1314
import static org.apiguardian.api.API.Status.STABLE;
1415

1516
import java.util.Objects;
@@ -71,8 +72,10 @@ public String getClassName() {
7172
}
7273

7374
/**
74-
* Get the class loader used to load the selected class.
75+
* Get the {@link ClassLoader} used to load the selected class.
76+
* @since 1.10
7577
*/
78+
@API(status = EXPERIMENTAL, since = "1.10")
7679
public ClassLoader getClassLoader() {
7780
return this.classLoader;
7881
}
@@ -86,10 +89,13 @@ public ClassLoader getClassLoader() {
8689
*/
8790
public Class<?> getJavaClass() {
8891
if (this.javaClass == null) {
89-
final Try<Class<?>> clazz = this.classLoader == null ? ReflectionUtils.tryToLoadClass(this.className)
90-
: ReflectionUtils.tryToLoadClass(className, this.classLoader);
91-
this.javaClass = clazz.getOrThrow(cause -> new PreconditionViolationException(
92-
"Could not load class with name: " + this.className, cause));
92+
// @formatter:off
93+
Try<Class<?>> tryToLoadClass = this.classLoader == null
94+
? ReflectionUtils.tryToLoadClass(this.className)
95+
: ReflectionUtils.tryToLoadClass(this.className, this.classLoader);
96+
this.javaClass = tryToLoadClass.getOrThrow(cause ->
97+
new PreconditionViolationException("Could not load class with name: " + this.className, cause));
98+
// @formatter:on
9399
}
94100
return this.javaClass;
95101
}
@@ -121,7 +127,12 @@ public int hashCode() {
121127

122128
@Override
123129
public String toString() {
124-
return new ToStringBuilder(this).append("className", this.className).toString();
130+
// @formatter:off
131+
return new ToStringBuilder(this)
132+
.append("className", this.className)
133+
.append("classLoader", this.classLoader)
134+
.toString();
135+
// @formatter:on
125136
}
126137

127138
}

junit-platform-engine/src/main/java/org/junit/platform/engine/discovery/DiscoverySelectors.java

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -384,25 +384,25 @@ public static ClassSelector selectClass(Class<?> clazz) {
384384
/**
385385
* Create a {@code ClassSelector} for the supplied class name.
386386
*
387-
* @param className the fully qualified name of the class to select;
388-
* never {@code null} or blank
387+
* @param className the fully qualified name of the class to select; never
388+
* {@code null} or blank
389389
* @see ClassSelector
390390
*/
391391
public static ClassSelector selectClass(String className) {
392-
Preconditions.notBlank(className, "Class name must not be null or blank");
393-
return new ClassSelector(className);
392+
return selectClass(className, null);
394393
}
395394

396395
/**
397-
* Create a {@code ClassSelector} for the supplied class name using the
398-
* supplied class loader.
396+
* Create a {@code ClassSelector} for the supplied class name and class loader.
399397
*
400-
* @param className the fully qualified name of the class to select;
401-
* never {@code null} or blank
402-
* @param classLoader the class loader to use to try and load the
403-
* supplied class. If {@code null}, the default class loader will be used.
398+
* @param className the fully qualified name of the class to select; never
399+
* {@code null} or blank
400+
* @param classLoader the class loader to use to load the class, or {@code null}
401+
* to signal that the default {@code ClassLoader} should be used
402+
* @since 1.10
404403
* @see ClassSelector
405404
*/
405+
@API(status = EXPERIMENTAL, since = "1.10")
406406
public static ClassSelector selectClass(String className, ClassLoader classLoader) {
407407
Preconditions.notBlank(className, "Class name must not be null or blank");
408408
return new ClassSelector(className, classLoader);
@@ -446,8 +446,8 @@ public static ClassSelector selectClass(String className, ClassLoader classLoade
446446
* <tr><td>{@code example.Service.process(String[][])}</td><td>{@code example.Service#process(java.lang.String[][])}</td></tr>
447447
* </table>
448448
*
449-
* @param fullyQualifiedMethodName the fully qualified name of the method to select; never
450-
* {@code null} or blank
449+
* @param fullyQualifiedMethodName the fully qualified name of the method to
450+
* select; never {@code null} or blank
451451
* @see MethodSelector
452452
*/
453453
public static MethodSelector selectMethod(String fullyQualifiedMethodName) throws PreconditionViolationException {
@@ -456,14 +456,21 @@ public static MethodSelector selectMethod(String fullyQualifiedMethodName) throw
456456

457457
/**
458458
* Create a {@code MethodSelector} for the supplied <em>fully qualified
459-
* method name</em> using the given classloader.
459+
* method name</em> and class loader.
460460
*
461-
* @param fullyQualifiedMethodName the fully qualified name of the method to select; never
462-
* {@code null} or blank (see {@link #selectMethod(String)} for the format of this string).
463-
* @param classLoader the class loader to use to try and load the
464-
* supplied class. If {@code null}, the default class loader will be used.
461+
* <p>See {@link #selectMethod(String)} for the supported formats for a
462+
* fully qualified method name.
463+
*
464+
* @param fullyQualifiedMethodName the fully qualified name of the method to
465+
* select; never {@code null} or blank
466+
* @param classLoader the class loader to use to load the method's declaring
467+
* class, or {@code null} to signal that the default {@code ClassLoader}
468+
* should be used
469+
* @since 1.10
465470
* @see #selectMethod(String)
471+
* @see MethodSelector
466472
*/
473+
@API(status = EXPERIMENTAL, since = "1.10")
467474
public static MethodSelector selectMethod(String fullyQualifiedMethodName, ClassLoader classLoader)
468475
throws PreconditionViolationException {
469476
String[] methodParts = ReflectionUtils.parseFullyQualifiedMethodName(fullyQualifiedMethodName);
@@ -484,16 +491,18 @@ public static MethodSelector selectMethod(String className, String methodName) {
484491
}
485492

486493
/**
487-
* Create a {@code MethodSelector} for the supplied class name and method name, using
488-
* the given class loader to find the class.
494+
* Create a {@code MethodSelector} for the supplied class name, method name,
495+
* and class loader.
489496
*
490497
* @param className the fully qualified name of the class in which the method
491498
* is declared, or a subclass thereof; never {@code null} or blank
492499
* @param methodName the name of the method to select; never {@code null} or blank
493-
* @param classLoader the class loader to use to try and load the
494-
* supplied class. If {@code null}, the default class loader will be used.
500+
* @param classLoader the class loader to use to load the class, or {@code null}
501+
* to signal that the default {@code ClassLoader} should be used
502+
* @since 1.10
495503
* @see MethodSelector
496504
*/
505+
@API(status = EXPERIMENTAL, since = "1.10")
497506
public static MethodSelector selectMethod(String className, String methodName, ClassLoader classLoader) {
498507
Preconditions.notBlank(className, "Class name must not be null or blank");
499508
Preconditions.notBlank(methodName, "Method name must not be null or blank");
@@ -522,7 +531,7 @@ public static MethodSelector selectMethod(String className, String methodName, S
522531

523532
/**
524533
* Create a {@code MethodSelector} for the supplied class name, method name,
525-
* and method parameter types, using the specified class loader.
534+
* method parameter types, and class loader.
526535
*
527536
* <p>The parameter types {@code String} is typically a comma-separated list
528537
* of atomic types, fully qualified class names, or array types; however,
@@ -534,8 +543,12 @@ public static MethodSelector selectMethod(String className, String methodName, S
534543
* @param methodParameterTypes the method parameter types as a single string; never
535544
* {@code null} though potentially an empty string if the method does not accept
536545
* arguments
546+
* @param classLoader the class loader to use to load the class, or {@code null}
547+
* to signal that the default {@code ClassLoader} should be used
548+
* @since 1.10
537549
* @see MethodSelector
538550
*/
551+
@API(status = EXPERIMENTAL, since = "1.10")
539552
public static MethodSelector selectMethod(String className, String methodName, String methodParameterTypes,
540553
ClassLoader classLoader) {
541554
Preconditions.notBlank(className, "Class name must not be null or blank");

junit-platform-engine/src/main/java/org/junit/platform/engine/discovery/MethodSelector.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
package org.junit.platform.engine.discovery;
1212

13+
import static org.apiguardian.api.API.Status.EXPERIMENTAL;
1314
import static org.apiguardian.api.API.Status.STABLE;
1415

1516
import java.lang.reflect.Method;
@@ -63,15 +64,15 @@ public class MethodSelector implements DiscoverySelector {
6364
private Method javaMethod;
6465

6566
MethodSelector(String className, String methodName) {
66-
this(className, methodName, "", (ClassLoader) null);
67+
this(className, methodName, (ClassLoader) null);
6768
}
6869

6970
MethodSelector(String className, String methodName, ClassLoader classLoader) {
7071
this(className, methodName, "", classLoader);
7172
}
7273

7374
MethodSelector(String className, String methodName, String methodParameterTypes) {
74-
this(className, methodName, methodParameterTypes, (ClassLoader) null);
75+
this(className, methodName, methodParameterTypes, null);
7576
}
7677

7778
MethodSelector(String className, String methodName, String methodParameterTypes, ClassLoader classLoader) {
@@ -110,8 +111,10 @@ public String getClassName() {
110111
}
111112

112113
/**
113-
* Get the class loader used to load the specified class.
114+
* Get the {@link ClassLoader} used to load the specified class.
115+
* @since 1.10
114116
*/
117+
@API(status = EXPERIMENTAL, since = "1.10")
115118
public ClassLoader getClassLoader() {
116119
return this.classLoader;
117120
}
@@ -173,10 +176,11 @@ public Method getJavaMethod() {
173176
private void lazyLoadJavaClass() {
174177
if (this.javaClass == null) {
175178
// @formatter:off
176-
final Try<Class<?>> clazz = this.classLoader == null ? ReflectionUtils.tryToLoadClass(this.className)
177-
: ReflectionUtils.tryToLoadClass(className, this.classLoader);
178-
this.javaClass = clazz.getOrThrow(
179-
cause -> new PreconditionViolationException("Could not load class with name: " + this.className, cause));
179+
Try<Class<?>> tryToLoadClass = this.classLoader == null
180+
? ReflectionUtils.tryToLoadClass(this.className)
181+
: ReflectionUtils.tryToLoadClass(this.className, this.classLoader);
182+
this.javaClass = tryToLoadClass.getOrThrow(cause ->
183+
new PreconditionViolationException("Could not load class with name: " + this.className, cause));
180184
// @formatter:on
181185
}
182186
}
@@ -235,6 +239,7 @@ public String toString() {
235239
.append("className", this.className)
236240
.append("methodName", this.methodName)
237241
.append("methodParameterTypes", this.methodParameterTypes)
242+
.append("classLoader", this.classLoader)
238243
.toString();
239244
// @formatter:on
240245
}

platform-tests/src/test/java/org/junit/platform/engine/discovery/ClassSelectorTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,10 @@ void preservesOriginalExceptionWhenTryingToLoadClass() {
4545
}
4646

4747
@Test
48-
void useClassClassLoader() {
48+
void usesClassClassLoader() {
4949
var selector = new ClassSelector(getClass());
5050

5151
assertThat(selector.getClassLoader()).isNotNull().isSameAs(getClass().getClassLoader());
5252
}
53+
5354
}

platform-tests/src/test/java/org/junit/platform/engine/discovery/DiscoverySelectorsTests.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
import java.io.File;
3434
import java.lang.reflect.Method;
3535
import java.net.URI;
36-
import java.net.URLClassLoader;
3736
import java.nio.file.Path;
3837
import java.nio.file.Paths;
3938
import java.util.List;
@@ -248,12 +247,12 @@ void selectClassByName() {
248247

249248
@Test
250249
void selectClassByNameAndClassLoader() throws Exception {
251-
try (TestClassLoader l = TestClassLoader.forClasses(getClass())) {
252-
ClassSelector selector = selectClass(getClass().getName(), l);
253-
assertEquals(getClass().getTypeName(), selector.getJavaClass().getTypeName());
250+
try (var testClassLoader = TestClassLoader.forClasses(getClass())) {
251+
ClassSelector selector = selectClass(getClass().getName(), testClassLoader);
252+
assertEquals(getClass().getName(), selector.getJavaClass().getName());
254253
assertNotEquals(getClass(), selector.getJavaClass());
255-
assertSame(l, selector.getClassLoader());
256-
assertSame(l, selector.getJavaClass().getClassLoader());
254+
assertSame(testClassLoader, selector.getClassLoader());
255+
assertSame(testClassLoader, selector.getJavaClass().getClassLoader());
257256
}
258257
}
259258

@@ -337,12 +336,12 @@ void selectMethodByFullyQualifiedName() throws Exception {
337336

338337
@Test
339338
void selectMethodByFullyQualifiedNameAndClassLoader() throws Exception {
340-
try (URLClassLoader l = TestClassLoader.forClasses(getClass())) {
341-
Class<?> clazz = l.loadClass(getClass().getTypeName());
339+
try (var testClassLoader = TestClassLoader.forClasses(getClass())) {
340+
Class<?> clazz = testClassLoader.loadClass(getClass().getName());
342341
assertNotEquals(getClass(), clazz);
343342

344343
Method method = clazz.getDeclaredMethod("myTest");
345-
MethodSelector selector = selectMethod(getClass().getName(), "myTest", l);
344+
MethodSelector selector = selectMethod(getClass().getName(), "myTest", testClassLoader);
346345
assertEquals(method, selector.getJavaMethod());
347346
assertEquals(clazz, selector.getJavaClass());
348347
assertEquals(clazz.getName(), selector.getClassName());

platform-tests/src/test/java/org/junit/platform/engine/discovery/MethodSelectorTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ void preservesOriginalExceptionWhenTryingToLoadClass() {
5252
void usesClassClassLoader() {
5353
var selector = new MethodSelector(getClass(), "usesClassClassLoader");
5454

55-
assertThat(selector.getClassLoader()).isNotNull().isEqualTo(getClass().getClassLoader());
55+
assertThat(selector.getClassLoader()).isNotNull().isSameAs(getClass().getClassLoader());
5656
}
5757

5858
}

platform-tests/src/test/java/org/junit/platform/launcher/listeners/discovery/LoggingLauncherDiscoveryListenerTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ void logsErrorOnSelectorResolutionFailure(LogRecordListener log) {
8080
assertThat(log.stream(LoggingLauncherDiscoveryListener.class, Level.SEVERE)) //
8181
.extracting(LogRecord::getMessage) //
8282
.containsExactly(
83-
"Resolution of ClassSelector [className = 'java.lang.Object'] by [engine:some-engine] failed");
83+
"Resolution of ClassSelector [className = 'java.lang.Object', classLoader = null] by [engine:some-engine] failed");
8484
}
8585

8686
@Test

0 commit comments

Comments
 (0)