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?
 
     
    