Skip to content

Java 11 and ForkJoinPool.commonPool() class loading issue #15737

@hanson76

Description

@hanson76

I'm trying to migrate an application from Java 8 to java 11 and have found a problem with
ServiceLoader.load() that are being run from within ForkJoinPool.commonPool, that are used by
default when using CompletableFuture.*Async().

The problem is that the commonPool that is created has ClassLoaders$AppClassLoader as class loader
in Java 11 while the applications classes are loaded into LaunchedURLClassLoader.

The problem with this is that if the applications code uses a ServiceLoader.load() from within
a ForkJoinPool.commonPool thread it wont find any classes that are located in any of the .jar files
packaged inside the jar/war file. ServiceLoader.load() uses Thread.currentThread().getContextClassLoader() to load classes.

I've not figured out a workaround for this problem.
There is a way to configure a different thread factory for the ForkJoinPool.commonPool by setting
a system property, but that is not working with Spring boot. There is no way to add own classes
to the .jar file that spring-boot maven plugin creates. The class has to be on the application class path
and therefor need to be a .class inside the root .jar.

There are lot of opensource projects out there that are using ServiceLoader to inject implementations at runtime that will not work if triggered from a CompletableFuture chain.

This is with Spring boot 2.1.2.RELEASE

Metadata

Metadata

Assignees

No one assigned

    Labels

    status: invalidAn issue that we don't feel is valid

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions