Skip to content

Commit

Permalink
Increase compatibility with GraalVM
Browse files Browse the repository at this point in the history
- Avoid early static initialization during native image compilation
  where possible
- Use and document `--initialize-at-build-time` build argument
  • Loading branch information
marcphilipp committed Jan 23, 2023
1 parent 9464843 commit 880fc6f
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ repository on GitHub.

==== Deprecations and Breaking Changes

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

==== New Features and Improvements

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
*/
class EngineIdValidator {

private static final Logger logger = LoggerFactory.getLogger(EngineIdValidator.class);

private EngineIdValidator() {
}

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

private static Logger getLogger() {
// Not a constant to avoid problems with building GraalVM native images
return LoggerFactory.getLogger(EngineIdValidator.class);
}

// https://github.com/junit-team/junit5/issues/1557
private static boolean validateReservedIds(TestEngine testEngine) {
String engineId = testEngine.getId();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,6 @@
@API(status = STABLE, since = "1.0")
public class LauncherFactory {

private static final ServiceLoaderRegistry SERVICE_LOADER_REGISTRY = new ServiceLoaderRegistry();

private LauncherFactory() {
/* no-op */
}
Expand Down Expand Up @@ -151,7 +149,7 @@ private static List<LauncherInterceptor> collectLauncherInterceptors(
LauncherConfigurationParameters configurationParameters) {
if (configurationParameters.getBoolean(ENABLE_LAUNCHER_INTERCEPTORS).orElse(false)) {
List<LauncherInterceptor> interceptors = new ArrayList<>();
SERVICE_LOADER_REGISTRY.load(LauncherInterceptor.class).forEach(interceptors::add);
ServiceLoaderRegistry.load(LauncherInterceptor.class).forEach(interceptors::add);
return interceptors;
}
return emptyList();
Expand All @@ -169,7 +167,7 @@ private static Set<TestEngine> collectTestEngines(LauncherConfig config) {
private static LauncherSessionListener createLauncherSessionListener(LauncherConfig config) {
ListenerRegistry<LauncherSessionListener> listenerRegistry = ListenerRegistry.forLauncherSessionListeners();
if (config.isLauncherSessionListenerAutoRegistrationEnabled()) {
SERVICE_LOADER_REGISTRY.load(LauncherSessionListener.class).forEach(listenerRegistry::add);
ServiceLoaderRegistry.load(LauncherSessionListener.class).forEach(listenerRegistry::add);
}
config.getAdditionalLauncherSessionListeners().forEach(listenerRegistry::add);
return listenerRegistry.getCompositeListener();
Expand All @@ -178,15 +176,15 @@ private static LauncherSessionListener createLauncherSessionListener(LauncherCon
private static List<PostDiscoveryFilter> collectPostDiscoveryFilters(LauncherConfig config) {
List<PostDiscoveryFilter> filters = new ArrayList<>();
if (config.isPostDiscoveryFilterAutoRegistrationEnabled()) {
SERVICE_LOADER_REGISTRY.load(PostDiscoveryFilter.class).forEach(filters::add);
ServiceLoaderRegistry.load(PostDiscoveryFilter.class).forEach(filters::add);
}
filters.addAll(config.getAdditionalPostDiscoveryFilters());
return filters;
}

private static void registerLauncherDiscoveryListeners(LauncherConfig config, Launcher launcher) {
if (config.isLauncherDiscoveryListenerAutoRegistrationEnabled()) {
SERVICE_LOADER_REGISTRY.load(LauncherDiscoveryListener.class).forEach(
ServiceLoaderRegistry.load(LauncherDiscoveryListener.class).forEach(
launcher::registerLauncherDiscoveryListeners);
}
config.getAdditionalLauncherDiscoveryListeners().forEach(launcher::registerLauncherDiscoveryListeners);
Expand All @@ -203,7 +201,7 @@ private static void registerTestExecutionListeners(LauncherConfig config, Launch

private static Stream<TestExecutionListener> loadAndFilterTestExecutionListeners(
ConfigurationParameters configurationParameters) {
Iterable<TestExecutionListener> listeners = SERVICE_LOADER_REGISTRY.load(TestExecutionListener.class);
Iterable<TestExecutionListener> listeners = ServiceLoaderRegistry.load(TestExecutionListener.class);
String deactivatedListenersPattern = configurationParameters.get(
DEACTIVATE_LISTENERS_PATTERN_PROPERTY_NAME).orElse(null);
// @formatter:off
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,16 @@
*/
class ServiceLoaderRegistry {

private static final Logger logger = LoggerFactory.getLogger(ServiceLoaderRegistry.class);

<T> Iterable<T> load(Class<T> serviceProviderClass) {
static <T> Iterable<T> load(Class<T> serviceProviderClass) {
Iterable<T> listeners = ServiceLoader.load(serviceProviderClass, ClassLoaderUtils.getDefaultClassLoader());
logger.config(() -> "Loaded " + serviceProviderClass.getSimpleName() + " instances: "
getLogger().config(() -> "Loaded " + serviceProviderClass.getSimpleName() + " instances: "
+ stream(listeners.spliterator(), false).map(Object::toString).collect(toList()));
return listeners;
}

private static Logger getLogger() {
// Not a constant to avoid problems with building GraalVM native images
return LoggerFactory.getLogger(ServiceLoaderRegistry.class);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,16 @@ public final class ServiceLoaderTestEngineRegistry {
public ServiceLoaderTestEngineRegistry() {
}

private static final Logger logger = LoggerFactory.getLogger(ServiceLoaderTestEngineRegistry.class);

public Iterable<TestEngine> loadTestEngines() {
Iterable<TestEngine> testEngines = ServiceLoader.load(TestEngine.class,
ClassLoaderUtils.getDefaultClassLoader());
logger.config(() -> TestEngineFormatter.format("Discovered TestEngines", testEngines));
getLogger().config(() -> TestEngineFormatter.format("Discovered TestEngines", testEngines));
return testEngines;
}

private static Logger getLogger() {
// Not a constant to avoid problems with building GraalVM native images
return LoggerFactory.getLogger(ServiceLoaderTestEngineRegistry.class);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,12 @@ tasks.test {
)
}
}

graalvmNative {
binaries {
named("test") {
buildArgs.add("--initialize-at-build-time=org.junit.platform.launcher.core.LauncherConfig")
buildArgs.add("-H:+ReportExceptionStackTraces")
}
}
}

0 comments on commit 880fc6f

Please sign in to comment.