编辑:不,这不是如何解决Java 9中的java.lang.NoClassDefFoundError:javax / xml / bind / JAXBException的重复-正如您可以从我尝试的部分看出,我已经尝试了建议的解决方案。
情况:我们有一个依赖于JAXB的Tomcat上运行的Web应用程序。在迁移到Java 9期间,我们选择添加JAXB参考实现作为常规依赖项。在使用IDE 嵌入式Tomcat启动应用程序时一切正常,但在真实的Tomcat实例上运行时,会出现以下错误:
Caused by: java.lang.RuntimeException: javax.xml.bind.JAXBException:
Implementation of JAXB-API has not been found on module path or classpath.
- with linked exception:
[java.lang.ClassNotFoundException: com.sun.xml.internal.bind.v2.ContextFactory]
at [... our-code ...]
Caused by: javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:278) ~[jaxb-api-2.3.0.jar:2.3.0]
at javax.xml.bind.ContextFinder.find(ContextFinder.java:421) ~[jaxb-api-2.3.0.jar:2.3.0]
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:721) ~[jaxb-api-2.3.0.jar:2.3.0]
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:662) ~[jaxb-api-2.3.0.jar:2.3.0]
at [... our-code ...]
Caused by: java.lang.ClassNotFoundException: com.sun.xml.internal.bind.v2.ContextFactory
at jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582) ~[?:?]
at jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:190) ~[?:?]
at java.lang.ClassLoader.loadClass(ClassLoader.java:499) ~[?:?]
at javax.xml.bind.ServiceLoaderUtil.nullSafeLoadClass(ServiceLoaderUtil.java:122) ~[jaxb-api-2.3.0.jar:2.3.0]
at javax.xml.bind.ServiceLoaderUtil.safeLoadClass(ServiceLoaderUtil.java:155) ~[jaxb-api-2.3.0.jar:2.3.0]
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:276) ~[jaxb-api-2.3.0.jar:2.3.0]
at javax.xml.bind.ContextFinder.find(ContextFinder.java:421) ~[jaxb-api-2.3.0.jar:2.3.0]
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:721) ~[jaxb-api-2.3.0.jar:2.3.0]
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:662) ~[jaxb-api-2.3.0.jar:2.3.0]
at [... our-code ...]
注意:
在模块路径或类路径上未找到JAXB-API的实现。
这些是webapps/$app/WEB-INF/lib
中相关的文件:
jaxb-api-2.3.0.jar
jaxb-core-2.3.0.jar
jaxb-impl-2.3.0.jar
这里发生了什么事情?
我尝试过的
将JAR文件添加到Tomcat的CLASSPATH
也许在setenv.sh
中将JAR文件添加到Tomcat的类路径中会有所帮助?
CLASSPATH=
.../webapps/$app/WEB-INF/lib/jaxb-api-2.3.0.jar:
.../webapps/$app/WEB-INF/lib/jaxb-impl-2.3.0.jar:
.../webapps/$app/WEB-INF/lib/jaxb-core-2.3.0.jar:
.../webapps/$app/WEB-INF/lib/javax.activation-1.2.0.jar
不行:
Caused by: javax.xml.bind.JAXBException: ClassCastException: attempting to cast
jar:file:.../webapps/$app/WEB-INF/lib/jaxb-api-2.3.0.jar!/javax/xml/bind/JAXBContext.class to
jar:file:.../webapps/$app/WEB-INF/lib/jaxb-api-2.3.0.jar!/javax/xml/bind/JAXBContext.class.
Please make sure that you are specifying the proper ClassLoader.
at javax.xml.bind.ContextFinder.handleClassCastException(ContextFinder.java:157) ~[jaxb-api-2.3.0.jar:2.3.0]
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:300) ~[jaxb-api-2.3.0.jar:2.3.0]
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:286) ~[jaxb-api-2.3.0.jar:2.3.0]
at javax.xml.bind.ContextFinder.find(ContextFinder.java:409) ~[jaxb-api-2.3.0.jar:2.3.0]
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:721) ~[jaxb-api-2.3.0.jar:2.3.0]
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:662) ~[jaxb-api-2.3.0.jar:2.3.0]
at de.disy.gis.webmapserver.factory.DefaultWmsRequestFactory.initializeCommandExtractor(DefaultWmsRequestFactory.java:103) ~[cadenza-gis-webmapserver-7.7-SNAPSHOT.jar:7.6]
at de.disy.gis.webmapserver.factory.DefaultWmsRequestFactory.lambda$new$0(DefaultWmsRequestFactory.java:87) ~[cadenza-gis-webmapserver-7.7-SNAPSHOT.jar:7.6]
显然这是同一个类,因此很可能被两个类加载器加载。我怀疑系统类加载器和应用程序的类加载器,但为什么加载JAXBContext
会有时委派给系统类加载器而有时不会呢?它看起来几乎像是应用程序的类加载器的委派行为在程序运行时发生了变化。
添加模块
我并不真正想添加java.xml.bind,但我还是尝试了一下,在catalina.sh
中加入了以下内容:
JDK_JAVA_OPTIONS="$JDK_JAVA_OPTIONS --add-modules=java.xml.bind"
但这也不起作用:
Caused by: java.lang.ClassCastException:
java.xml.bind/com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl
cannot be cast to com.sun.xml.bind.v2.runtime.JAXBContextImpl
at [... our-code ...]
除了不同的类和堆栈跟踪,这与之前发生的情况一致:类
JAXBContextImpl
被加载了两次,一次来自java.xml.bind(必须是系统类加载器),另一次是来自应用程序的加载器从JAR中加载。
搜索错误
搜索Tomcat的错误数据库我找到#62559。那可能是相同的错误吗?
向Tomcat的lib
添加JAR
按照Tomcat用户邮件列表上给出的建议,我将JAXB JAR添加到Tomcat的CATALINA_BASE/lib
目录中,但在应用程序的lib文件夹中仍然遇到了相同的错误。
newInstance
重载的Javadoc。如果您需要更多细节,您必须让我知道他们需要解释什么。 - Nicolai Parlog