Skip to content

Commit 880fc6f

Browse files
committed
Increase compatibility with GraalVM
- Avoid early static initialization during native image compilation where possible - Use and document `--initialize-at-build-time` build argument
1 parent 9464843 commit 880fc6f

File tree

6 files changed

+35
-18
lines changed

6 files changed

+35
-18
lines changed

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ repository on GitHub.
1919

2020
==== Deprecations and Breaking Changes
2121

22-
* ❓
22+
* Building native images with GraalVM now requires configuring the build arg
23+
`--initialize-at-build-time=org.junit.platform.launcher.core.LauncherConfig`.
2324

2425
==== New Features and Improvements
2526

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

+6-3
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323
*/
2424
class EngineIdValidator {
2525

26-
private static final Logger logger = LoggerFactory.getLogger(EngineIdValidator.class);
27-
2826
private EngineIdValidator() {
2927
}
3028

@@ -33,7 +31,7 @@ static Iterable<TestEngine> validate(Iterable<TestEngine> testEngines) {
3331
for (TestEngine testEngine : testEngines) {
3432
// check usage of reserved id prefix
3533
if (!validateReservedIds(testEngine)) {
36-
logger.warn(() -> String.format(
34+
getLogger().warn(() -> String.format(
3735
"Third-party TestEngine implementations are forbidden to use the reserved 'junit-' prefix for their ID: '%s'",
3836
testEngine.getId()));
3937
}
@@ -47,6 +45,11 @@ static Iterable<TestEngine> validate(Iterable<TestEngine> testEngines) {
4745
return testEngines;
4846
}
4947

48+
private static Logger getLogger() {
49+
// Not a constant to avoid problems with building GraalVM native images
50+
return LoggerFactory.getLogger(EngineIdValidator.class);
51+
}
52+
5053
// https://github.com/junit-team/junit5/issues/1557
5154
private static boolean validateReservedIds(TestEngine testEngine) {
5255
String engineId = testEngine.getId();

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

+5-7
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,6 @@
6666
@API(status = STABLE, since = "1.0")
6767
public class LauncherFactory {
6868

69-
private static final ServiceLoaderRegistry SERVICE_LOADER_REGISTRY = new ServiceLoaderRegistry();
70-
7169
private LauncherFactory() {
7270
/* no-op */
7371
}
@@ -151,7 +149,7 @@ private static List<LauncherInterceptor> collectLauncherInterceptors(
151149
LauncherConfigurationParameters configurationParameters) {
152150
if (configurationParameters.getBoolean(ENABLE_LAUNCHER_INTERCEPTORS).orElse(false)) {
153151
List<LauncherInterceptor> interceptors = new ArrayList<>();
154-
SERVICE_LOADER_REGISTRY.load(LauncherInterceptor.class).forEach(interceptors::add);
152+
ServiceLoaderRegistry.load(LauncherInterceptor.class).forEach(interceptors::add);
155153
return interceptors;
156154
}
157155
return emptyList();
@@ -169,7 +167,7 @@ private static Set<TestEngine> collectTestEngines(LauncherConfig config) {
169167
private static LauncherSessionListener createLauncherSessionListener(LauncherConfig config) {
170168
ListenerRegistry<LauncherSessionListener> listenerRegistry = ListenerRegistry.forLauncherSessionListeners();
171169
if (config.isLauncherSessionListenerAutoRegistrationEnabled()) {
172-
SERVICE_LOADER_REGISTRY.load(LauncherSessionListener.class).forEach(listenerRegistry::add);
170+
ServiceLoaderRegistry.load(LauncherSessionListener.class).forEach(listenerRegistry::add);
173171
}
174172
config.getAdditionalLauncherSessionListeners().forEach(listenerRegistry::add);
175173
return listenerRegistry.getCompositeListener();
@@ -178,15 +176,15 @@ private static LauncherSessionListener createLauncherSessionListener(LauncherCon
178176
private static List<PostDiscoveryFilter> collectPostDiscoveryFilters(LauncherConfig config) {
179177
List<PostDiscoveryFilter> filters = new ArrayList<>();
180178
if (config.isPostDiscoveryFilterAutoRegistrationEnabled()) {
181-
SERVICE_LOADER_REGISTRY.load(PostDiscoveryFilter.class).forEach(filters::add);
179+
ServiceLoaderRegistry.load(PostDiscoveryFilter.class).forEach(filters::add);
182180
}
183181
filters.addAll(config.getAdditionalPostDiscoveryFilters());
184182
return filters;
185183
}
186184

187185
private static void registerLauncherDiscoveryListeners(LauncherConfig config, Launcher launcher) {
188186
if (config.isLauncherDiscoveryListenerAutoRegistrationEnabled()) {
189-
SERVICE_LOADER_REGISTRY.load(LauncherDiscoveryListener.class).forEach(
187+
ServiceLoaderRegistry.load(LauncherDiscoveryListener.class).forEach(
190188
launcher::registerLauncherDiscoveryListeners);
191189
}
192190
config.getAdditionalLauncherDiscoveryListeners().forEach(launcher::registerLauncherDiscoveryListeners);
@@ -203,7 +201,7 @@ private static void registerTestExecutionListeners(LauncherConfig config, Launch
203201

204202
private static Stream<TestExecutionListener> loadAndFilterTestExecutionListeners(
205203
ConfigurationParameters configurationParameters) {
206-
Iterable<TestExecutionListener> listeners = SERVICE_LOADER_REGISTRY.load(TestExecutionListener.class);
204+
Iterable<TestExecutionListener> listeners = ServiceLoaderRegistry.load(TestExecutionListener.class);
207205
String deactivatedListenersPattern = configurationParameters.get(
208206
DEACTIVATE_LISTENERS_PATTERN_PROPERTY_NAME).orElse(null);
209207
// @formatter:off

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

+7-4
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,16 @@
2424
*/
2525
class ServiceLoaderRegistry {
2626

27-
private static final Logger logger = LoggerFactory.getLogger(ServiceLoaderRegistry.class);
28-
29-
<T> Iterable<T> load(Class<T> serviceProviderClass) {
27+
static <T> Iterable<T> load(Class<T> serviceProviderClass) {
3028
Iterable<T> listeners = ServiceLoader.load(serviceProviderClass, ClassLoaderUtils.getDefaultClassLoader());
31-
logger.config(() -> "Loaded " + serviceProviderClass.getSimpleName() + " instances: "
29+
getLogger().config(() -> "Loaded " + serviceProviderClass.getSimpleName() + " instances: "
3230
+ stream(listeners.spliterator(), false).map(Object::toString).collect(toList()));
3331
return listeners;
3432
}
3533

34+
private static Logger getLogger() {
35+
// Not a constant to avoid problems with building GraalVM native images
36+
return LoggerFactory.getLogger(ServiceLoaderRegistry.class);
37+
}
38+
3639
}

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

+6-3
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,16 @@ public final class ServiceLoaderTestEngineRegistry {
2929
public ServiceLoaderTestEngineRegistry() {
3030
}
3131

32-
private static final Logger logger = LoggerFactory.getLogger(ServiceLoaderTestEngineRegistry.class);
33-
3432
public Iterable<TestEngine> loadTestEngines() {
3533
Iterable<TestEngine> testEngines = ServiceLoader.load(TestEngine.class,
3634
ClassLoaderUtils.getDefaultClassLoader());
37-
logger.config(() -> TestEngineFormatter.format("Discovered TestEngines", testEngines));
35+
getLogger().config(() -> TestEngineFormatter.format("Discovered TestEngines", testEngines));
3836
return testEngines;
3937
}
4038

39+
private static Logger getLogger() {
40+
// Not a constant to avoid problems with building GraalVM native images
41+
return LoggerFactory.getLogger(ServiceLoaderTestEngineRegistry.class);
42+
}
43+
4144
}

platform-tooling-support-tests/projects/graalvm-starter/build.gradle.kts

+9
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,12 @@ tasks.test {
2727
)
2828
}
2929
}
30+
31+
graalvmNative {
32+
binaries {
33+
named("test") {
34+
buildArgs.add("--initialize-at-build-time=org.junit.platform.launcher.core.LauncherConfig")
35+
buildArgs.add("-H:+ReportExceptionStackTraces")
36+
}
37+
}
38+
}

0 commit comments

Comments
 (0)