相关疑难解决方法(0)

CompletableFuture/ForkJoinPool设置类加载器

我解决了一个非常具体的问题,其解决方案似乎是基本的:

我的(Spring)应用程序的类加载器层次结构是这样的: SystemClassLoader -> PlatformClassLoader -> AppClassLoader

如果我使用Java CompleteableFuture来运行线程.该ContextClassLoader线程的是: SystemClassLoader -> PlatformClassLoader -> ThreadClassLoader

因此,AppClassLoader虽然我必须访问任何类,但我无法访问任何类,因为所有外部库类都驻留在那里.

源代码库非常大,所以我不希望/不能将所有与线程相关的部分重写为其他内容(例如,将自定义执行程序传递给每个调用).

所以我的问题是:我怎样才能创建线程,例如CompleteableFuture.supplyAsync()使用AppClassLoader父母作为父母?(而不是PlatformClassloader)

我发现ForkJoinPool用于创建线程.但在我看来,一切都是静态的最终的.所以我怀疑即使在系统属性中设置自定义ForkJoinWorkerThreadFactory也会有所帮助.或者是吗?

编辑以回答评论中的问题:

  • 你在哪里部署?这是在jetty/tomcat /任何JEE容器内运行吗?

    • 我正在使用默认的Spring Boot设置,因此使用了内部tomcat容器.
  • 你有什么确切的问题?

    • 确切的问题是:java.lang.IllegalArgumentException:从类加载器中看不到从方法引用的org.keycloak.admin.client.resource.RealmsResource
  • 您提交给supplyAsync()的作业是从AppClassLoader创建的,不是吗?

    • supplyAsync从被称为MainThread它使用AppClassLoader.但是,调试应用程序会显示所有此类线程都具有PlatformClassLoader父级.至于我的理解,这是因为ForkJoinPool.commonPool()是在应用程序启动期间构建的(因为它是静态的),所以使用默认的类加载器作为父类PlatformClassLoader.因此,此池中的所有线程都将PlatformClassLoader作为ContextClassLoader的父级(而不是AppClassLoader).

    • 当我在内部创建自己的执行程序MainThread并将此执行程序传递给supplyAsync所有工作时 - 我可以在调试期间看到确实现在AppClassLoader是我的父项ThreadClassLoader.这似乎证实了我在第一种情况下的假设,即公共池MainThread至少不是在它自己使用时创建的 …

java spring classloader completable-future

13
推荐指数
4
解决办法
1238
查看次数

迁移到雅加达:ClassNotFoundException:com.sun.xml.internal.ws.spi.ProviderImpl

根据https://wiki.eclipse.org/New_Maven_Coordinates和Maven Central从Java 8迁移到Java 11并从EE切换到最新的Jakarta库时,我们在(仍基于SOAP的)客户端应用程序中获得了以下运行时异常:

Exception in thread "main" javax.xml.ws.WebServiceException: Provider com.sun.xml.internal.ws.spi.ProviderImpl not found
        at javax.xml.ws.spi.FactoryFinder$1.createException(FactoryFinder.java:31)
        at javax.xml.ws.spi.FactoryFinder$1.createException(FactoryFinder.java:28)
        at javax.xml.ws.spi.ServiceLoaderUtil.newInstance(ServiceLoaderUtil.java:73)
        at javax.xml.ws.spi.FactoryFinder.find(FactoryFinder.java:82)
        at javax.xml.ws.spi.Provider.provider(Provider.java:66)
        at javax.xml.ws.Service.<init>(Service.java:82)
        at [...]
Caused by: java.lang.ClassNotFoundException: com.sun.xml.internal.ws.spi.ProviderImpl
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        at javax.xml.ws.spi.ServiceLoaderUtil.nullSafeLoadClass(ServiceLoaderUtil.java:60)
        at javax.xml.ws.spi.ServiceLoaderUtil.safeLoadClass(ServiceLoaderUtil.java:93)
        at javax.xml.ws.spi.ServiceLoaderUtil.newInstance(ServiceLoaderUtil.java:71)
        ... 5 more
Run Code Online (Sandbox Code Playgroud)

尽管定义了依赖项,但获取java.lang.ClassNotFoundException:com.sun.xml.internal.ws.spi.ProviderImpl中描述的解决方案不起作用,也不使用Jakarta。

如果我没看错,则Jarkarta库中不应包含“ com.sun.xml。”包或此类引用,但javax.xml.ws.spi.Provider显然仍会引用此类:

private static final String DEFAULT_JAXWSPROVIDER =
        "com.sun"+".xml.internal.ws.spi.ProviderImpl";
Run Code Online (Sandbox Code Playgroud)

那么,有谁知道是否有一个与缺少的包含ProviderImpl的库等效的Jakarta,或者我如何解决Jakarta的问题?

提前致谢!

soap java-11 jakarta-ee

1
推荐指数
2
解决办法
754
查看次数