我解决了一个非常具体的问题,其解决方案似乎是基本的:
我的(Spring)应用程序的类加载器层次结构是这样的: SystemClassLoader -> PlatformClassLoader -> AppClassLoader
如果我使用Java CompleteableFuture来运行线程.该ContextClassLoader线程的是: SystemClassLoader -> PlatformClassLoader -> ThreadClassLoader
因此,AppClassLoader虽然我必须访问任何类,但我无法访问任何类,因为所有外部库类都驻留在那里.
源代码库非常大,所以我不希望/不能将所有与线程相关的部分重写为其他内容(例如,将自定义执行程序传递给每个调用).
所以我的问题是:我怎样才能创建线程,例如CompleteableFuture.supplyAsync()使用AppClassLoader父母作为父母?(而不是PlatformClassloader)
我发现ForkJoinPool用于创建线程.但在我看来,一切都是静态的和最终的.所以我怀疑即使在系统属性中设置自定义ForkJoinWorkerThreadFactory也会有所帮助.或者是吗?
编辑以回答评论中的问题:
你在哪里部署?这是在jetty/tomcat /任何JEE容器内运行吗?
你有什么确切的问题?
您提交给supplyAsync()的作业是从AppClassLoader创建的,不是吗?
在supplyAsync从被称为MainThread它使用AppClassLoader.但是,调试应用程序会显示所有此类线程都具有PlatformClassLoader父级.至于我的理解,这是因为ForkJoinPool.commonPool()是在应用程序启动期间构建的(因为它是静态的),所以使用默认的类加载器作为父类PlatformClassLoader.因此,此池中的所有线程都将PlatformClassLoader作为ContextClassLoader的父级(而不是AppClassLoader).
当我在内部创建自己的执行程序MainThread并将此执行程序传递给supplyAsync所有工作时 - 我可以在调试期间看到确实现在AppClassLoader是我的父项ThreadClassLoader.这似乎证实了我在第一种情况下的假设,即公共池MainThread至少不是在它自己使用时创建的 …
根据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的问题?
提前致谢!