Java 设置要使用的 JAXB 上下文工厂初始化类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19731507/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Set the JAXB context factory initialization class to be used
提问by JBA
I have updated our projects (Java EE based running on Websphere 8.5) to use a new release of a company internal framework (and Ejb 3.x deployment descriptors rather than the 2.x ones). Since then my integration Tests fail with the following exception:
我已经更新了我们的项目(基于 Java EE 运行在 Websphere 8.5 上)以使用公司内部框架的新版本(以及 Ejb 3.x 部署描述符而不是 2.x 部署描述符)。从那时起,我的集成测试失败,但出现以下异常:
[java.lang.ClassNotFoundException: com.ibm.xml.xlxp2.jaxb.JAXBContextFactory]
I can build the application with the previous framework release and everything works fine. While debugging i noticed that within the ContextFinder (javax.xml.bind) there are two different behaviours:
我可以使用以前的框架版本构建应用程序,并且一切正常。在调试时,我注意到在 ContextFinder (javax.xml.bind) 中有两种不同的行为:
Previous Version (Everything works just fine): None of the different places brings up a factory class so the default factory class gets loaded which is com.sun.xml.internal.bind.v2.ContextFactory (defined as String constant within the class).
Upgraded Version (ClassNotFound): There is a resource "META-INF/services/javax.xml.bind.JAXBContext" beeing loaded successfully and the first line read makes the ContextFinder attempt to load "com.ibm.xml.xlxp2.jaxb.JAXBContextFactory" which causes the error.
以前的版本(一切正常):不同的地方都没有提供工厂类,因此默认工厂类被加载,即 com.sun.xml.internal.bind.v2.ContextFactory(定义为类中的字符串常量) .
升级版本 (ClassNotFound):有一个资源“META-INF/services/javax.xml.bind.JAXBContext”正在成功加载,第一行读取使 ContextFinder 尝试加载“com.ibm.xml.xlxp2.jaxb。 JAXBContextFactory”导致错误。
I now have two questions:
我现在有两个问题:
What sort is that resource? Because inside our EAR there is two WARs and none of those two contains a folder services in its META-INF directory.
Where could that value be from otherwise? Because a filediff showed me no new or changed properties files.
那个资源是什么类型的?因为在我们的 EAR 中有两个 WAR,并且这两个 WAR 都没有在其 META-INF 目录中包含文件夹服务。
否则,该价值从何而来?因为 filediff 没有显示我没有新的或更改的属性文件。
No need to say i am going to read all about the JAXB configuration possibilities but if you have first insights on what could have gone wrong or help me out with that resource (is it a real file i have to look for?) id appreciate a lot. Many Thanks!
无需说我将阅读有关 JAXB 配置可能性的所有内容,但是如果您对可能出现的问题有初步了解或帮助我解决该资源(我必须寻找的真实文件吗?)我很感激很多。非常感谢!
EDIT (according to comments Input/Questions):
编辑(根据评论输入/问题):
Out of curiosity, does your framework include JAXB JARs? Did the old version of your framework include jaxb.properties?
出于好奇,您的框架是否包含 JAXB JAR?旧版本的框架是否包含 jaxb.properties?
Indeed (i am a bit surprised) the framework has a customized eclipselink-2.4.1-.jar inside the EAR that includes both a JAXB implementation and a jaxb.properties file that shows the following entry in both versions (the one that finds the factory as well as in the one that throws the exception):
事实上(我有点惊讶)该框架在 EAR 中有一个定制的 eclipselink-2.4.1-.jar,其中包括一个 JAXB 实现和一个 jaxb.properties 文件,该文件显示了两个版本中的以下条目(找到工厂以及抛出异常的工厂):
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
I think this is has nothing to do with the current issue since the jar stayed exactly the same in both EARs (the one that runs/ the one with the expection)
我认为这与当前问题无关,因为罐子在两个 EAR 中保持完全相同(运行的那个/预期的那个)
It's also not clear to me why the old version of the framework was ever selecting the com.sun implementation
我也不清楚为什么旧版本的框架会选择 com.sun 实现
There is a class javax.xml.bind.ContextFinder which is responsible for initializing the JAXBContextFactory. This class searches various placess for the existance of a jaxb.properties file or a "javax.xml.bind.JAXBContext" resource. If ALL of those places dont show up which Context Factory to use there is a deault factory loaded which is hardcoded in the class itself:
有一个类 javax.xml.bind.ContextFinder 负责初始化 JAXBContextFactory。此类在各个位置搜索 jaxb.properties 文件或“javax.xml.bind.JAXBContext”资源的存在。如果所有这些地方都没有显示要使用的上下文工厂,则加载了一个默认工厂,它在类本身中进行了硬编码:
private static final String PLATFORM_DEFAULT_FACTORY_CLASS = "com.sun.xml.internal.bind.v2.ContextFactory";
Now back to my problem:
现在回到我的问题:
Building with the previous version of the framework (and EJB 2.x deployment descriptors) everything works fine). While debugging i can see that there is no configuration found and thatfore above mentioned default factory is loaded.
使用先前版本的框架(和 EJB 2.x 部署描述符)构建一切正常)。在调试时,我可以看到没有找到配置,因此加载了上述默认工厂。
Building with the new version of the framework (and EJB 3.x deployment descriptors so i can deploy) ONLY A TESTCASE fails but the rest of the functionality works (like i can send requests to our webservice and they dont trigger any errors). While debugging i can see that there is a configuration found. This resource is named "META-INF/services/javax.xml.bind.JAXBContext". Here are the most important lines of how this resource leads to the attempt to load 'com.ibm.xml.xlxp2.jaxb.JAXBContextFactory' which then throws the ClassNotFoundException. This is simplified source of the mentioned javax.xml.bind.ContextFinder class:
使用新版本的框架(和 EJB 3.x 部署描述符,以便我可以部署)构建只有一个 TESTCASE 失败,但其余功能有效(就像我可以向我们的 web 服务发送请求,它们不会触发任何错误)。在调试时,我可以看到找到了一个配置。此资源名为“META-INF/services/javax.xml.bind.JAXBContext”。以下是此资源如何导致尝试加载“com.ibm.xml.xlxp2.jaxb.JAXBContextFactory”的最重要的几行,然后抛出 ClassNotFoundException。这是提到的 javax.xml.bind.ContextFinder 类的简化源:
URL resourceURL = ClassLoader.getSystemResource("META-INF/services/javax.xml.bind.JAXBContext");
BufferedReader r = new BufferedReader(new InputStreamReader(resourceURL.openStream(), "UTF-8"));
String factoryClassName = r.readLine().trim();
The field factoryClassName now has the value 'com.ibm.xml.xlxp2.jaxb.JAXBContextFactory'
字段 factoryClassName 现在具有值 'com.ibm.xml.xlxp2.jaxb.JAXBContextFactory'
Because this has become a super lager question i will also add a bounty :) I will work the entire day on this and let you know if there is any news.
因为这已经成为一个超级大的问题,我还将添加一个赏金:) 我将为此工作一整天,如果有任何消息,请告诉您。
Update/ Solution
更新/解决方案
This question has been solved. The original problem has occured because misconfiguration of complexly build multi model maven projects which one dependency used a updated version of a customized eclipse link jar that contained a definition for a JAXBFactory not available in the component where the error occured. Setting the JAXB context factory in most cases is configured with a jaxb.propertie file or JAXBContext file that contains the same definition. Detailed loading process of the appropriate JAXBContextFactory happens in javax.xml.bind.ContextFinder.
这个问题已经解决了。最初的问题是因为复杂构建的多模型 maven 项目的错误配置,其中一个依赖项使用了自定义 eclipse 链接 jar 的更新版本,其中包含在发生错误的组件中不可用的 JAXBFactory 定义。在大多数情况下,设置 JAXB 上下文工厂是使用包含相同定义的 jaxb.propertie 文件或 JAXBContext 文件进行配置的。相应 JAXBContextFactory 的详细加载过程发生在 javax.xml.bind.ContextFinder 中。
The error has not yet been solved (during the fact over 4 major EE/SE Applications lead to the error) and there is no general answer but that defined JAXBContextFactorys must exist in your classpath (wow what a wonder...) so you either have a that ClassNotFound Error because youre missing resources (well thats the acctual cause) or because you have a wrong JAXBContextFactory defined in any of the above mentioned propertie files which contain a definition according to the below answer.
错误尚未解决(事实上超过 4 个主要的 EE/SE 应用程序导致错误)并且没有通用的答案,但是定义的 JAXBContextFactorys 必须存在于您的类路径中(哇,真是奇迹……)所以您要么有一个 ClassNotFound 错误,因为您缺少资源(这是实际原因),或者因为您在上述任何属性文件中定义了错误的 JAXBContextFactory,其中包含根据以下答案的定义。
Very many thanks for your great comments and support, i realy appreciate!
非常感谢您的宝贵意见和支持,我真的很感激!
采纳答案by bdoughan
You can include a jaxb.properties
file in the same package as your domain model to specify the JAXB (JSR-222) implementation you wish to use. For example it would look like the following to specify EclipseLink MOXyas your JAXB provider.
您可以jaxb.properties
在与域模型相同的包中包含一个文件,以指定您希望使用的 JAXB ( JSR-222) 实现。例如,将EclipseLink MOXy指定为您的 JAXB 提供程序将如下所示。
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
For More Information
想要查询更多的信息
回答by schnatterer
Another quick and dirtysolution (a workaround, really) that worked for me is to explicitly include a JAXB implementation to the maven build. For example
另一个对我有用的快速而肮脏的解决方案(实际上是一种解决方法)是将 JAXB 实现显式包含到 Maven 构建中。例如
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.2.7</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.2.7</version>
</dependency>
Note that this adds a somehow unnecessary dependency to your build, as JAXB obviously already is part of each JRE >= version 6.
请注意,这会在某种程度上为您的构建增加不必要的依赖,因为 JAXB 显然已经是每个 JRE >= 版本 6 的一部分。
Most likely this will only work when the WAS classloader is set to parent last.
这很可能只有在 WAS 类加载器最后设置为父级时才有效。