I upgraded my spring boot application from Java 8 and tomcat 8 to java 11 and tomcat 9. Everything seems to work fine except the part that I use parallel streams on lists.
list.addAll(items
.parallelStream()
.filter(item -> !SomeFilter.isOk(item.getId()))
.map(logic::getSubItem)
.collect(Collectors.toList()));
The previous part of code used to work fine with Java 8 and Tomcat 8 but after Java 9 changes on how the classes are loaded with Fork/Join common pool threads return the system class loader as their thread context class loader.
I know that under the hood parallel streams use ForkJoinPool and I created a custom bean class but still, it is not used by the app. Most probably due to the fact that maybe they are created before this bean.
@Bean
public ForkJoinPool myForkJoinPool() {
return new ForkJoinPool(threadPoolSize, makeFactory("APP"), null, false);
}
private ForkJoinPool.ForkJoinWorkerThreadFactory makeFactory(String prefix) {
return pool -> {
final ForkJoinWorkerThread worker = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
worker.setName(prefix + worker.getPoolIndex());
worker.setContextClassLoader(Application.class.getClassLoader());
return worker;
};
}
Lastly, I also tried to wrap it around an instance of my ForkJoinPool but it is done asynchronously and I do not want to. I also do not want to use the submit and get because that means that I have to wrap up all the parallel stream that I have on the application with try/catch and the code will be nasty to read.
forkJoinPool.execute(() ->
list.addAll(items
.parallelStream()
.filter(item -> !SomeFilter.isOk(item.getId()))
.map(logic::getSubItem)
.collect(Collectors.toList())));
Ideally, I would like all my parallel streams that are used in the application to use the class loader from the application and not the system one.
Any idea?
If using a third-party is an option, you could use the Parallel Collectors library:
list.addAll(items
.stream()
.filter(item -> !SomeFilter.isOk(item.getId()))
.collect(parallel(logic::getSubItem, Collectors.toList(), forkJoinPool)
.join());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With