I considered a very specific problem, the solution of which seems to be something simple:
My (Spring) hierarchy of application class loaders looks something like this: SystemClassLoader -> PlatformClassLoader -> AppClassLoader
If I use Java CompleteableFutureto run threads. ContextClassLoaderthreads:SystemClassLoader -> PlatformClassLoader -> ThreadClassLoader
Thus, I cannot access any class in AppClassLoader, although I must, because all the classes of external libraries are there.
The source database is quite large, so I don’t want / cannot rewrite all the parts associated with the flows into something else (for example, transfer my own executor to each call).
So my question is: How can I create themes created, for example, to CompleteableFuture.supplyAsync()use AppClassLoaderas a parent? (instead PlatformClassloader)
I found that ForkJoinPool is used to create threads. But, as it seems to me, everything is static and final. Therefore, I doubt that even setting a custom ForkJoinWorkerThreadFactory with a system property will help in this case. Or will it be?
Edit to answer questions from comments:
where do you deploy? Does it work in Jetty / Tomcat / any JEE container?
- I use the default Spring Boot setting, so the Tomcat internal container is used.
What is your specific problem?
- Exact problem: java.lang.IllegalArgumentException: org.keycloak.admin.client.resource.RealmsResource the method refers to is not visible in the class loader
Jobs that you submit to supplyAsync () are created from AppClassLoader, right?
supplyAsync MainThread, AppClassLoader. , PlatformClassLoader . , , ForkJoinPool.commonPool() ( ) , PlatformClassLoader. , PlatformClassLoader ContextClassLoader ( AppClassLoader).
MainThread supplyAsync, - , AppClassLoader ThreadClassLoader. , -, , MainThread, , AppClassLoader.
:
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]