diff --git a/core/src/main/java/io/micronaut/core/convert/DefaultConversionService.java b/core/src/main/java/io/micronaut/core/convert/DefaultConversionService.java index dec55ff153c..d381dae4625 100644 --- a/core/src/main/java/io/micronaut/core/convert/DefaultConversionService.java +++ b/core/src/main/java/io/micronaut/core/convert/DefaultConversionService.java @@ -960,7 +960,12 @@ protected void registerDefaultConverters() { Collection registrars = new ArrayList<>(); ForkJoinPool forkJoinPool = new ForkJoinPool(); // Create a custom ForkJoinPool to prevent deadlock - SoftServiceLoader.load(TypeConverterRegistrar.class).collectAll(registrars, null, forkJoinPool); + SoftServiceLoader.load(TypeConverterRegistrar.class) + .withForkJoinPool(forkJoinPool) + .collectAll(registrars); + for (TypeConverterRegistrar registrar : registrars) { + registrar.register(this); + } forkJoinPool.shutdown(); } diff --git a/core/src/main/java/io/micronaut/core/io/service/ServiceScanner.java b/core/src/main/java/io/micronaut/core/io/service/ServiceScanner.java index 73ca1cfac9d..8127ce042a1 100644 --- a/core/src/main/java/io/micronaut/core/io/service/ServiceScanner.java +++ b/core/src/main/java/io/micronaut/core/io/service/ServiceScanner.java @@ -152,8 +152,13 @@ private void findMicronautMetaServiceConfigs(BiConsumer consumer) t @SuppressWarnings("java:S1948") final class DefaultServiceCollector extends RecursiveActionValuesCollector implements SoftServiceLoader.ServiceCollector { + private final ForkJoinPool forkJoinPool; private final List> tasks = new ArrayList<>(); + DefaultServiceCollector(ForkJoinPool forkJoinPool) { + this.forkJoinPool = forkJoinPool; + } + @Override protected void compute() { try { diff --git a/core/src/main/java/io/micronaut/core/io/service/SoftServiceLoader.java b/core/src/main/java/io/micronaut/core/io/service/SoftServiceLoader.java index d0c86811d69..2cbdac6c5f4 100644 --- a/core/src/main/java/io/micronaut/core/io/service/SoftServiceLoader.java +++ b/core/src/main/java/io/micronaut/core/io/service/SoftServiceLoader.java @@ -29,6 +29,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.concurrent.ForkJoinPool; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; @@ -57,6 +58,7 @@ public final class SoftServiceLoader implements Iterable private Collection> servicesForIterator; private final Predicate condition; private boolean allowFork = true; + private ForkJoinPool forkJoinPool = ForkJoinPool.commonPool(); private SoftServiceLoader(Class serviceType, ClassLoader classLoader) { this(serviceType, classLoader, (String name) -> true); @@ -112,6 +114,11 @@ public SoftServiceLoader disableFork() { return this; } + public SoftServiceLoader withForkJoinPool(ForkJoinPool forkJoinPool) { + this.forkJoinPool = forkJoinPool; + return this; + } + /** * @return Return the first such instance */ @@ -194,7 +201,7 @@ private void collectDynamicServices( throw new ServiceLoadingException(e); } return null; - }); + }, forkJoinPool); collector.collect(values, allowFork); } @@ -254,7 +261,7 @@ public Iterator> iterator() { } catch (NoClassDefFoundError | ClassNotFoundException e) { return createService(name, null); } - }).collect(serviceDefinitions, false); + }, forkJoinPool).collect(serviceDefinitions, false); this.servicesForIterator = serviceDefinitions; } } @@ -284,11 +291,19 @@ private ServiceDefinition createService(String name, Class loadedClass) { return new DefaultServiceDefinition<>(name, loadedClass); } + public static ServiceCollector newCollector(String serviceName, + Predicate lineCondition, + ClassLoader classLoader, + Function transformer, + ForkJoinPool forkJoinPool) { + return new ServiceScanner<>(classLoader, serviceName, lineCondition, transformer).new DefaultServiceCollector(forkJoinPool); + } + public static ServiceCollector newCollector(String serviceName, Predicate lineCondition, ClassLoader classLoader, Function transformer) { - return new ServiceScanner<>(classLoader, serviceName, lineCondition, transformer).new DefaultServiceCollector(); + return new ServiceScanner<>(classLoader, serviceName, lineCondition, transformer).new DefaultServiceCollector(ForkJoinPool.commonPool()); } /**