Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java parallelStream()导致JAXB-API出现ClassNotFoundException_Java_Jaxb_Classloader_Java 11 - Fatal编程技术网

Java parallelStream()导致JAXB-API出现ClassNotFoundException

Java parallelStream()导致JAXB-API出现ClassNotFoundException,java,jaxb,classloader,java-11,Java,Jaxb,Classloader,Java 11,在我们的应用程序中,有时会出现以下异常: javax.xml.bind.JAXBException:在模块路径或类路径上未找到JAXB-API的实现。 -除此之外: [java.lang.ClassNotFoundException:com.sun.xml.internal.bind.v2.ContextFactory] 我们已经发现,只有使用Collection.parallelStream()时才会发生这种情况,但如果使用Collection.stream(),则不会发生这种情况 我们看到

在我们的应用程序中,有时会出现以下异常:

javax.xml.bind.JAXBException:在模块路径或类路径上未找到JAXB-API的实现。
-除此之外:
[java.lang.ClassNotFoundException:com.sun.xml.internal.bind.v2.ContextFactory]
我们已经发现,只有使用
Collection.parallelStream()
时才会发生这种情况,但如果使用
Collection.stream()
,则不会发生这种情况

我们看到JAXB使用
Thread.currentThread().getContextClassLoader()
加载类。我们还看到,当使用
parallelStream()
时,执行命令的线程使用不同的类装入器。有时是
org.apache.catalina.loader.WebappClassLoader
,有时是
jdk.internal.loader.ClassLoaders.AppClassLoader

现在看来,
AppClassLoader
不知道JAXB依赖项,而
WebappClassLoader
知道

我们正在使用Java 11和以下Maven依赖项:


javax.xml.bind
jaxb api
2.3.1
org.glassfish.jaxb
jaxb运行时
2.3.1
javax.activation
激活
1.1.1

你知道会出什么问题吗?
AppClassLoader
怎么可能不知道我们的依赖关系呢?

我遇到了类似的问题,我在
org.apache.xerces.parsers.SAXParser
中得到了ClassNotFoundException。我已经删除/排除了对
xercesImpl
XMLAPI
xmlbeans
xmlschema core
的依赖关系,问题得到了解决,尽管我不知道为什么以及它是如何工作的。促使我删除这些jar的是XMLReaderFactory,它出现在
jdk8
xmlapi
中,我们有不同的体验。问题是tomcat的类加载器与每一个war不同(我认为我们在spring boot应用程序中看到了类似的东西;void main与application runner不同)

不管是哪种方式,问题在于“引导”类加载器无法访问应用程序中的JAR,因此没有jaxb。因此,如果您曾经从
StreamXX.parallel()
ForkJoinPool.commonThreadPool()
启动线程(如
ForkJoinPoolThread
),那么这些线程将来自引导类加载器,而不是应用程序的类加载器。。因此,如果您的后台任务第一次加载JAXB,它们将运行
getClass().getContextClassLoader().getResourceAsStream(“xxxx”)
,并且找不到资源

我们的解决方案是在显式线程池中启动所有后台任务,并拥有显式线程池工厂。。线程池工厂从调用线程(由war或spring启动上下文初始化的线程)捕获类加载器。这个类加载器将有jaxb和朋友。。因此,现在从这个线程池工厂启动的每个线程都有一个显式的
thr.setContextClassLoader(globalCL)

问题已解决(通过黑客)

该类
以前在
rt.jar
文件中提供,直到
Java8
,然后从
jdk
中删除


可能原因:您的应用程序使用了一些库,这些库使用了一些旧库,它们需要
Java8
,其中包含
xml.bind
,它从
JDK11
中删除



解决方法:您只需从
jdk8
复制文件
/usr/lib/jvm/jre-1.8.0-openjdk/lib/rt.jar
,对其内容稍加修剪,只保存
com.sun.xml.internal.bind.
包。然后将这个
jar
放到您的
tomcat/lib
文件夹中。

您正在从某处加载旧版本的JAXB。在Java 11中,上下文工厂应该是:
com.sun.xml.bind.v2.ContextFactory

而不是

com.sun.xml.internal.bind.v2.ContextFactory

尝试执行以下操作: 将激活包升级到1.2。我不确定这和它有什么关系,但由于您使用的是Java11,我建议您使用Activation1.2

而不是插入jaxB的glassfish实现。使用以下依赖项:


javax.xml.bind
jaxb api
2.3.0
com.sun.xml.bind
jaxb内核
2.3.0
com.sun.xml.bind
jaxb impl
2.3.0
或交替地


jakarta.xml.bind
jakarta.xml.bind-api
2.3.3
如果这仍然不起作用,请回到我写给你的第一封信:

正确的上下文工厂是:

com.sun.xml.bind.v2.ContextFactory

某个地方加载了一个旧的vesion。

行为的变化是在JDK9中引入的:(由于)

另见