OSGi跨bundle调用,jaxb-impl异常

news/2024/4/20 20:54:16/文章来源:https://blog.csdn.net/p793049488/article/details/129239920

问题

环境:JDK11

为什么是JDK11,由于jaxb是作为JDK8的一部分,在JDK11中已经被剥离出来需要单独引入。

项目中使用osgi架构,在处理xml解析的实现中使用了jdk自带的Javax.xml.bind包。在单模块结构工程中都没有问题,但是引到插件化模式工程结构中,会提示找不到JaxbContext的工厂类而报错。具体报错信息如下:

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) ~[na:na]at javax.xml.bind.ContextFinder.find(ContextFinder.java:421) ~[na:na]at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:721) ~[na:na]at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:662) ~[na:na]at com.ruijie.pctool.plugins.device.pojo.bo.PluginLoaderExt.fromXml(PluginLoaderExt.java:79) ~[na:na]... 32 common frames omitted
Caused by: java.lang.ClassNotFoundException: com.sun.xml.internal.bind.v2.ContextFactoryat java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:476) ~[na:na]at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:589) ~[na:na]at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522) ~[na:na]at org.eclipse.osgi.internal.framework.ContextFinder.loadClass(ContextFinder.java:135) ~[na:na]at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522) ~[na:na]at javax.xml.bind.ServiceLoaderUtil.nullSafeLoadClass(ServiceLoaderUtil.java:122) ~[na:na]at javax.xml.bind.ServiceLoaderUtil.safeLoadClass(ServiceLoaderUtil.java:155) ~[na:na]at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:276) ~[na:na]... 36 common frames omitted
JavaFX Application Thread

导入的依赖:(这里shade包是继承了jaxb的api,impl,runtime等包的合集)

<dependency><groupId>com.ruijie.osgi.thirdparty</groupId><artifactId>javax.xml.bind.shade</artifactId><version>2.3.1.v202203241600</version>
</dependency>

原因分析

在引入的包中,所提供的工厂类为com.sun.xml.bind.v2.ContextFactory,并不是错误提示的com.sun.xml.internal.bind.v2.ContextFactory;

其实jaxb提供了几种构建jaxbcontext的方式,如果都匹配不到,那么会使用系统默认指定的com.sun.xml.internal.bind.v2.ContextFactory来构建,但是不知道为什么指定了一个jar不存在的包路径:

javax.xml.bind.ContextFinder#find(java.lang.String, java.lang.String, java.lang.ClassLoader, java.util.Map)

JaxbContext源码

static JAXBContext find(String factoryId, String contextPath, ClassLoader classLoader, Map properties) throws JAXBException {if (contextPath != null && !contextPath.isEmpty()) {Class[] contextPathClasses = ModuleUtil.getClassesFromContextPath(contextPath, classLoader);String factoryClassName = jaxbProperties(contextPath, classLoader, factoryId);if (factoryClassName == null && contextPathClasses != null) {factoryClassName = jaxbProperties(contextPathClasses, factoryId);}if (factoryClassName != null) {return newInstance(contextPath, contextPathClasses, factoryClassName, classLoader, properties);} else {String factoryName = classNameFromSystemProperties();if (factoryName != null) {return newInstance(contextPath, contextPathClasses, factoryName, classLoader, properties);} else {JAXBContextFactory obj = (JAXBContextFactory)ServiceLoaderUtil.firstByServiceLoader(JAXBContextFactory.class, logger, EXCEPTION_HANDLER);if (obj != null) {ModuleUtil.delegateAddOpensToImplModule(contextPathClasses, obj.getClass());return obj.createContext(contextPath, classLoader, properties);} else {factoryName = firstByServiceLoaderDeprecated(JAXBContext.class, classLoader);if (factoryName != null) {return newInstance(contextPath, contextPathClasses, factoryName, classLoader, properties);} else {Class ctxFactory = (Class)ServiceLoaderUtil.lookupUsingOSGiServiceLoader("javax.xml.bind.JAXBContext", logger);if (ctxFactory != null) {return newInstance(contextPath, contextPathClasses, ctxFactory, classLoader, properties);} else {logger.fine("Trying to create the platform default provider");return newInstance(contextPath, contextPathClasses, ModuleUtil.DEFAULT_FACTORY_CLASS, classLoader, properties);}}}}}} else {throw new JAXBException(Messages.format("ContextFinder.NoPackageInContextPath"));}}

1、首先,寻找系统是否自定义jaxb.properties,指明所需的工厂类全限定名

2、其次,寻找系统是否配置了系统变量javax.xml.bind.JAXBContextFactory来指定工厂对象

3、接着,寻找jaxb包提供的META-INF/servies/javax.xml.bind.JAXBContextFactory配置文件,里面配置了所需的工厂类全限定名

4、若还是没有,lookuposgibundle寻找

5、若还是没有,就构建系统默认指定的com.sun.xml.internal.bind.v2.ContextFactory;由于该路径下不存在这个类,所以直接报错

按理,jaxb包提供的META-INF/servies/javax.xml.bind.JAXBContextFactory这个文件存在的情况下,为什么还是没被识别到呢?猜测由于OSGi的隔离机制,在跨bundle使用过程中读取不到该配置文件。

解决

由于jaxb-api提供了SPI的扩展机制,基于他的实现很多,所以集成了如下的依赖解决该问题:

<!-- jaxb-api实现需要的依赖 -->
<dependency><groupId>com.ruijie.osgi.thirdparty</groupId><artifactId>javax.karta.xml.bind-api</artifactId><version>2.3.3.v20220331-2000</version>
</dependency>
<dependency><groupId>com.ruijie.osgi.thirdparty</groupId><artifactId>javax.karta.activation</artifactId><version>1.2.2.v20220331-2000</version>
</dependency>
<dependency><groupId>com.ruijie.osgi.thirdparty</groupId><artifactId>com.sun.xml.bind.jaxb-osgi</artifactId><version>2.3.6.v2022331-2000</version>
</dependency>
<dependency><groupId>com.ruijie.osgi.thirdparty</groupId><artifactId>org.glassfish.osgi-resource-locator</artifactId><version>2.4.0.v20220331-2000</version>
</dependency>

问题解决。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_74763.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

spring boot maven打包jar包太大,怎么办?这个方法解决你的烦恼

在springboot maven项目中&#xff0c;有两种打包方式&#xff0c;一种是war包&#xff0c;一种是jar&#xff0c;今天我们讲一下jar的打包方式。但是在jar包打包只要我们发现&#xff0c;我们的项目jar太大了&#xff0c;每次上传到服务器的时候非常的慢&#xff0c;接下来我们…

大数据处理各组件概念及作用

一、数据采集&#xff1a; 1.1 Flume集群&#xff1a;数据采集工具&#xff0c;如写脚本将不同源端的数据采集后进行数据存储&#xff0c;或推送至Kafka等&#xff1b; 1.2 FTP集群&#xff1a;文件传输工具&#xff1b; 1.3 Kafka集群&#xff1a;消息队列&#xff0c;未避免…

高压放大器在应力波法套筒灌浆密实度检测研究中的应用

实验名称&#xff1a;高压放大器在应力波法套筒灌浆密实度检测研究中的应用研究方向&#xff1a;无损检测测试目的&#xff1a;钢筋套筒灌浆连接技术被广泛应用于装配式建筑节点连接中&#xff0c;但灌浆不密实将导致节点失效的风险。因此&#xff0c;施工中对套筒灌浆的密实度…

Spark 分析计算连续三周登录的用户数

前言&#xff1a;本文用到了窗口函数 range between&#xff0c;可以参考这篇博客进行了解——窗口函数rows between 、range between的使用 创建数据环境 在 MySQL 中创建数据测试表 log_data&#xff1a; create table if not exists log_data( log_id varchar(200) comm…

代码随想录【Day27】| 39. 组合总和、40. 组合总和 II、131. 分割回文串

39. 组合总和 题目链接 题目描述&#xff1a; 给定一个无重复元素的数组 candidates 和一个目标数 target &#xff0c;找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的数字可以无限制重复被选取。 说明&#xff1a; 所有数字&#xff08;包括 tar…

taobao.top.secret.bill.detail( 服务商的商家解密账单详情查询 )

&#xffe5;免费必须用户授权 服务商的商家解密账单详情查询&#xff0c;仅对90天内的账单提供SLA保障。 公共参数 请求地址: HTTP地址 http://gw.api.taobao.com/router/rest 公共请求参数: 公共响应参数: 请求参数 响应参数 点击获取key和secret 请求示例 TaobaoClient…

js 拖动--动态改变div的宽高大小

index.html 如下&#xff1a;&#xff08;可以新建一个index.html文件直接复制&#xff0c;打开运行&#xff09; <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta http-equiv"X-UA-Compatible&qu…

Mybatis源码学习笔记(五)之Mybatis框架缓存机制原理解析

1 Mybatis框架的缓存模块 MyBatis 内置了一个强大的事务性查询缓存机制&#xff0c;它可以非常方便地配置和定制。Mybatis框架中的缓存分为一级缓存和二级缓存&#xff0c;三级缓存基本都要借助自定义缓存或第三方服务来进行实现。但本质上是一样的&#xff0c;都是借助Cache接…

【Python学习笔记】第十九节 Python 面向对象(一)

在现实世界中&#xff0c;随处可见的一种事物就是对象&#xff0c;对象是事物存在的实体&#xff0c;如学生、汽车等。人类解决问题的方式总是将复杂的事物简单化&#xff0c;于是就会思考这些对象都是由哪些部分组成的。通常都会将对象划分为两个部分&#xff0c;即静态部分与…

SSL证书对虚拟主机的用处有哪些?

虚拟主机是指在同一台服务器上&#xff0c;通过不同的域名或IP地址为多个网站提供服务的一种网络主机。而SSL证书则是一种数字证书&#xff0c;它用于加密网站与用户之间的通信&#xff0c;确保数据传输的安全性和完整性。在虚拟主机上&#xff0c;SSL证书有以下几个用处&#…

HiveSql一天一个小技巧:如何巧用分布函数percent_rank()求去掉最大最小值的平均薪水问题

0 问题描述参考链接(3条消息) HiveSql面试题12--如何分析去掉最大最小值的平均薪水&#xff08;字节跳动&#xff09;_莫叫石榴姐的博客-CSDN博客文中已经给出了三种解法&#xff0c;这里我们借助于此题&#xff0c;来研究如何用percent_rank()函数求解&#xff0c;简化解题思路…

深入理解C#的协变和逆变及其限制原因

阅读本文需要的一些前置知识&#xff1a; C#基本语法、C#的泛型使用、C#的运行过程 由于协变和逆变存在一些细节&#xff0c;在阅读时请注意“接口”和“类型”的差异&#xff0c;此外&#xff0c;文中有可能在不同的语境中将“结构体”和“值类型”混用&#xff0c;但表达的同…

深入浅出1588v2(PTP)里的时间同步原理

1.时间同步1.1 单步同步(OneStep)单步同步最为简单&#xff0c;master向slave发送一个sync的同步包&#xff0c;同步包里带有这条信息发送时master的当前时间t1&#xff0c;假如这条信息从master传输到slave需要的传输时间是D&#xff0c;那么slave收到信息时&#xff0c;maste…

BIM小技巧丨关于如何在Revit明细表中显示门窗面积

在明细表中显示门窗面积(以门明细表为例)在新建一个门明细表后&#xff0c;可以发现在Revit中不能直接使用明细表统计门窗面积。 这时&#xff0c;可以通过使用添加“计算值”的方式来处理&#xff0c;得到如下图所示&#xff0c;两种不同的面积统计结果&#xff1a; 除此之外&…

前端基础之CSS扫盲

文章目录一. CSS基本规范1. 基本语法格式2. 在HTML引入CSS3. 选择器分类二. CSS常用属性1. 文本属性2. 文本格式3. 背景属性4. 圆角矩形和圆5. 元素的显示模式6. CSS盒子模型7. 弹性布局光使用HTML来写一个前端页面的话其实只是写了一个大体的框架, 整体的页面并不工整美观, 而…

ledcode【用队列实现栈】

目录 题目描述&#xff1a; 解析题目 代码解析 1.封装一个队列 1.2封装带两个队列的结构体 1.3封装指向队列的结构体 1.4入栈函数实现 1.5出栈函数实现 1.6取栈顶数据 1.7判空函数实现 题目描述&#xff1a; 解析题目 这个题我是用c语言写的&#xff0c;所以队列的pu…

JavaSE-3 Java运行原理

一、Java的运行过程 &#x1f34e;Java程序运行时,必须经过编译和运行两个步骤。 首先将后缀名为.java的源文件进行编译,最终生成后缀名为.class的字节码文件。然后Java虚拟机将字节码文件进行解释执行,并将结果显示出来。具体过程如下图所示。 &#x1f349;Java程序的运行过…

【Python数据挖掘入门】2.2文本分析-中文分词(jieba库cut方法/自定义词典load_userdict/语料库分词)

中文分词就是将一个汉字序列切分成一个一个单独的词。例如&#xff1a; 另外还有停用词的概念&#xff0c;停用词是指在数据处理时&#xff0c;需要过滤掉的某些字或词。 一、jieba库 安装过程见&#xff1a;https://blog.csdn.net/momomuabc/article/details/128198306 ji…

数字IC手撕代码--小米科技(除法器设计)

前言&#xff1a; 本专栏旨在记录高频笔面试手撕代码题&#xff0c;以备数字前端秋招&#xff0c;本专栏所有文章提供原理分析、代码及波形&#xff0c;所有代码均经过本人验证。目录如下&#xff1a;1.数字IC手撕代码-分频器&#xff08;任意偶数分频&#xff09;2.数字IC手撕…

原始GAN-pytorch-生成MNIST数据集(代码)

文章目录原始GAN生成MNIST数据集1. Data loading and preparing2. Dataset and Model parameter3. Result save path4. Model define6. Training7. predict原始GAN生成MNIST数据集 原理很简单&#xff0c;可以参考原理部分原始GAN-pytorch-生成MNIST数据集&#xff08;原理&am…