I tackled down a very specific problem, whose solution seems to be something basic:
My (Spring) application's classloader hierarchy is something like this: SystemClassLoader -> PlatformClassLoader -> AppClassLoader
If I use Java CompleteableFuture to run threads. the ContextClassLoader of the threads is:  SystemClassLoader -> PlatformClassLoader -> ThreadClassLoader
Thus, I cannot access any class in AppClassLoader although I have to because all external library classes reside there.
The source base is quite large so I don't want to/can't rewrite all the thread related pieces to something else (e.g. pass a custom executor to each call).
So my question is: How can I make the threads created by e.g. CompleteableFuture.supplyAsync() use the AppClassLoader as a parent? (instead of the PlatformClassloader)
I found out that ForkJoinPool is used to create the threads. But as it seems to me, everything there is static and final. So I doubt that even setting a custom ForkJoinWorkerThreadFactory with a system property will help in this case. Or would it?
Edit to answer the questions from the comments:
- where do you deploy to? Is this running within jetty / tomcat / any JEE container? - I'm using the default Spring Boot setup so an internal tomcat container is used.
 
- What is the exact issue you have? - The exact issue is: java.lang.IllegalArgumentException: org.keycloak.admin.client.resource.RealmsResource referenced from a method is not visible from class loader
 
- The jobs that you submit to supplyAsync() are created from the AppClassLoader, aren't they? - The - supplyAsyncis called from the- MainThreadwhich uses the- AppClassLoader. But, debugging the applications shows that all such threads have- PlatformClassLoaderas their parent. As to my understanding, this happens because ForkJoinPool.commonPool() is constructed during the application startup (because it's static) and so uses the default class loader as the parent which is- PlatformClassLoader. So, all threads from this pool get- PlatformClassLoaderas their parent for ContextClassLoader (instead of- AppClassLoader).
- When I'm creating my own executor inside the - MainThreadand pass this executor to- supplyAsynceverything works - and I can see during debugging that indeed now- AppClassLoaderis the parent of my- ThreadClassLoader. Which seems to affirm my assumption in the first case that the common pool is not created by- MainThreadat least not when it's using- AppClassLoaderitself.
 
Full stacktrace:
java.lang.IllegalArgumentException: org.keycloak.admin.client.resource.RealmsResource referenced from a method is not visible from class loader
    at java.base/java.lang.reflect.Proxy$ProxyBuilder.ensureVisible(Proxy.java:851) ~[na:na]
    at java.base/java.lang.reflect.Proxy$ProxyBuilder.validateProxyInterfaces(Proxy.java:682) ~[na:na]
    at java.base/java.lang.reflect.Proxy$ProxyBuilder.<init>(Proxy.java:628) ~[na:na]
    at java.base/java.lang.reflect.Proxy.lambda$getProxyConstructor$1(Proxy.java:426) ~[na:na]
    at java.base/jdk.internal.loader.AbstractClassLoaderValue$Memoizer.get(AbstractClassLoaderValue.java:327) ~[na:na]
    at java.base/jdk.internal.loader.AbstractClassLoaderValue.computeIfAbsent(AbstractClassLoaderValue.java:203) ~[na:na]
    at java.base/java.lang.reflect.Proxy.getProxyConstructor(Proxy.java:424) ~[na:na]
    at java.base/java.lang.reflect.Proxy.newProxyInstance(Proxy.java:999) ~[na:na]
    at org.jboss.resteasy.client.jaxrs.ProxyBuilder.proxy(ProxyBuilder.java:79) ~[resteasy-client-3.1.4.Final.jar!/:3.1.4.Final]
    at org.jboss.resteasy.client.jaxrs.ProxyBuilder.build(ProxyBuilder.java:131) ~[resteasy-client-3.1.4.Final.jar!/:3.1.4.Final]
    at org.jboss.resteasy.client.jaxrs.internal.ClientWebTarget.proxy(ClientWebTarget.java:93) ~[resteasy-client-3.1.4.Final.jar!/:3.1.4.Final]
    at org.keycloak.admin.client.Keycloak.realms(Keycloak.java:114) ~[keycloak-admin-client-3.4.3.Final.jar!/:3.4.3.Final]
    at org.keycloak.admin.client.Keycloak.realm(Keycloak.java:118) ~[keycloak-admin-client-3.4.3.Final.jar!/:3.4.3.Final]
 
     
     
     
    