当前位置: 首页 > 面试题库 >

设置要使用的JAXB上下文工厂初始化类

梁丘俊材
2023-03-14
问题内容

我已经更新了项目(基于Websphere 8.5的Java EE),以使用公司内部框架的新版本(以及Ejb
3.x部署描述符,而不是2.x部署描述符)。从那时起,我的集成测试失败,但出现以下异常:

 [java.lang.ClassNotFoundException: com.ibm.xml.xlxp2.jaxb.JAXBContextFactory]

我可以使用先前的框架版本构建应用程序,并且一切正常。调试时,我注意到ContextFinder(javax.xml.bind)中有两种不同的行为:

  1. 先前版本(一切正常):所有地方都没有调出工厂类,因此将加载默认工厂类com.sun.xml.internal.bind.v2.ContextFactory(在该类中定义为String常量)。 。

  2. 升级版本(ClassNotFound):成功加载了资源“ META-INF / services / javax.xml.bind.JAXBContext”,读取的第一行使ContextFinder尝试加载“ com.ibm.xml.xlxp2.jaxb”。 JAXBContextFactory”,从而导致错误。

我现在有两个问题:

  1. 那是什么资源?因为在我们的EAR内部有两个WAR,而这两个WAR都不在其META-INF目录中包含文件夹服务。

  2. 那个价值可能从何而来呢?因为filediff没有显示任何新的或更改的属性文件。

无需多说,我将阅读所有有关JAXB配置可能性的信息,但如果您对可能出错的内容有第一见,或者可以帮助我使用该资源(我是否要查找真实文件?)很多。非常感谢!

编辑(根据评论输入/问题):

出于好奇,您的框架是否包括JAXB JAR? 您的框架的旧版本是否包含jaxb.properties?

确实(我有点惊讶),该框架在EAR内部具有一个自定义的eclipselink-2.4.1-.jar,其中包括JAXB实现和jaxb.properties文件,该文件在两个版本中均显示以下条目(即找到工厂以及引发异常的工厂):

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

我认为这与当前问题无关,因为两个EAR中的jar保持完全相同(运行的那个/期望的那个)

我还不清楚为什么旧版本的框架曾经选择com.sun实现

有一个类javax.xml.bind.ContextFinder负责初始化JAXBContextFactory。此类在各种位置搜索jaxb.properties文件或“
javax.xml.bind.JAXBContext”资源的存在。如果所有这些地方都没有显示要使用的上下文工厂,则将加载一个装在工厂本身中的deault工厂:

private static final String PLATFORM_DEFAULT_FACTORY_CLASS = "com.sun.xml.internal.bind.v2.ContextFactory";

现在回到我的问题:

使用框架的先前版本(和EJB 2.x部署描述符)进行构建,一切正常。在调试时,我可以看到没有找到任何配置,并且上述默认工厂已加载。

使用新版本的框架(和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();

现在,字段factoryClassName的值为’com.ibm.xml.xlxp2.jaxb.JAXBContextFactory’

因为这已经成为一个超级大问题,所以我还将提供赏金:)我将全天为此工作,并让您知道是否有任何新闻。

更新/解决方案

这个问题已经解决。发生最初的问题是因为配置复杂的多模型Maven项目的配置错误,其中一个依赖项使用了自定义的Eclipse链接jar的更新版本,该更新版本包含一个JAXBFactory的定义,该定义在发生错误的组件中不可用。在大多数情况下,使用包含相同定义的jaxb.propertie文件或JAXBContext文件配置设置JAXB上下文工厂。适当的JAXBContextFactory的详细加载过程在javax.xml.bind.ContextFinder中进行。

该错误尚未解决(在超过4个主要EE /
SE应用程序导致错误的情况下),并且没有一般性的答案,但已定义的JAXBContextFactory必须存在于类路径中(真是一个奇迹…),所以您要么出现那个ClassNotFound错误,是因为您缺少资源(这可能是造成这种情况的原因),或者是您在上述任何属性文件中定义的JAXBContextFactory错误,该文件包含根据以下答案的定义。

非常感谢您的出色评论和支持,非常感谢!


问题答案:

您可以将jaxb.properties文件包含在与域模型相同的程序包中,以指定要使用的JAXB(
JSR-222
)实现。例如,如下所示将 EclipseLink
MOXy
指定为您的JAXB提供程序。

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

想要查询更多的信息

  • http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html


 类似资料:
  • 我尝试使用 Websphere 8.5 完整配置文件将应用程序转换为 Liberty 配置文件,但我遇到了有关不兼容的问题。 无法找到初始上下文工厂 我知道班级的位置com.ibm.ws.ejb.thinclient_8.0.0.jar在完整的配置文件中,但我不能在Liberty配置文件中找到相关的,还有一件事,因为我正在做维护应用程序,所以班级要看看。 com . IBM . WebSphere

  • 我有一个工厂,它应该根据名称返回一个实现。 为了让每次调用getMoules方法都不创建实例,有一个映射,其中所有的模块都必须在bootstrap类中初始化。我想摆脱手动操作的需要(也是所有的类都有一个显著的特征)。 我想到的选项列表: 反射(我们可以使用Scala反射API或任何第三方库) 自动化流程 需要在启动时立即初始化 反思是一种痛苦 宏只改变代码,执行稍后发生。 我们能把初始化过程移到编

  • 我试图在Python中初始化火花上下文变量。 但我得到了以下错误: py4j。协议Py4JJavaError:调用None时出错。组织。阿帕奇。火花应用程序编程接口。JAVAJavaSparkContext.:JAVAlang.NoClassDefFoundError:无法初始化类组织。阿帕奇。火花内部的配置。组织上的包$ 。阿帕奇。火花斯帕克孔夫。在组织上验证设置(SparkConf.scala

  • 我希望使用JMeter在Websphere MQ队列中创建测试负载。我只想将消息放置到队列中--所以我使用JMS Publisher Sampler。我拥有的配置项是:mqhost:port、MQChannel、MQQueueManager、MQQueue 在示例中,我输入了一些设置:Provider URL:tcp://mqhost:port destination:MQQueue 对于MQCh

  • 在我的Shiro应用程序中,我使用来定义我的领域。我像这样注册我的领域: 但是,Shiro找不到realms/MyRealm。我认为原因是,我需要定义的jndiUNEP,其中包含属性。但是,我不知道如何在我的中设置此属性: 我在TomEE上运行我的应用程序。 我当前的如下所示: