Carregador de classe Set CompletableFuture / ForkJoinPool

Eu lidei com um problema muito específico, cuja solução parece ser algo básico:

A hierarquia do carregador de classes do meu aplicativo (Spring) é mais ou menos assim:SystemClassLoader -> PlatformClassLoader -> AppClassLoader

Se eu uso JavaCompleteableFuture para executar threads. aContextClassLoader dos segmentos é:SystemClassLoader -> PlatformClassLoader -> ThreadClassLoader

Portanto, não consigo acessar nenhuma classe emAppClassLoader embora eu precise, porque todas as classes de bibliotecas externas residem lá.

A base de origem é bastante grande, então eu não quero / não posso reescrever todas as partes relacionadas ao thread para outra coisa (por exemplo, passar um executor personalizado para cada chamada).

Então, minha pergunta é:Como posso criar os threads criados por ex.CompleteableFuture.supplyAsync() use oAppClassLoader como pai? (ao invés dePlatformClassloader)

Eu descobri queForkJoinPool é usado para criar os threads. Mas, como me parece, tudo o que existeestático efinal. Então, duvido que, mesmo definindo um costumeForkJoinWorkerThreadFactory com uma propriedade de sistema ajudará neste caso. Ou seria?

Edite para responder às perguntas dos comentários:

onde você implanta? Isso está sendo executado no jetty / tomcat / algum contêiner JEE?

Estou usando a configuração padrão do Spring Boot para que um contêiner tomcat interno seja usado.

Qual é o problema exato que você tem?

O problema exato é:java.lang.IllegalArgumentException: org.keycloak.admin.client.resource.RealmsResource referenciado a partir de um método não é visível no carregador de classes

As tarefas que você envia para supplyAsync () são criadas a partir do AppClassLoader, não são?

osupplyAsync é chamado a partir doMainThread que usa oAppClassLoader. Porém, a depuração dos aplicativos mostra que todos esses threads têmPlatformClassLoader como pai. Quanto ao meu entendimento, isso acontece porqueForkJoinPool.commonPool () é construído durante a inicialização do aplicativo (porque é estático) e, portanto, usa o carregador de classes padrão como o pai que éPlatformClassLoader. Portanto, todos os threads desse pool sãoPlatformClassLoader como pai paraContextClassLoader (ao invés deAppClassLoader)

Quando estou criando meu próprio executor dentro doMainThread e passar esse executor parasupplyAsync tudo funciona - e eu posso ver durante a depuração que de fato agoraAppClassLoader é o pai da minhaThreadClassLoader. O que parece afirmar minha suposição no primeiro caso de que o pool comum não é criado porMainThread pelo menos não quando está usandoAppClassLoader em si.

Stacktrace completo:

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]

questionAnswers(2)

yourAnswerToTheQuestion