当前位置: 首页 > news >正文

记一次SPI机制导致的BUG定位【不支持:http://javax.xml.XMLConstants/property/accessExternalDTD】

1、前因

今天在生产环境启用了某个功能,结果发现有个文件上传华为云OBS失败了,报错如下:

Caused by: java.lang.IllegalArgumentException: 不支持:http://javax.xml.XMLConstants/property/accessExternalDTDat org.apache.xalan.processor.TransformerFactoryImpl.setAttribute(TransformerFactoryImpl.java:576) ~[xalan-2.7.1.jar:?]at com.obs.services.internal.xml.OBSXMLBuilder.asString(OBSXMLBuilder.java:306) ~[esdk-obs-java-bundle-3.23.9.1.jar:?]at com.obs.services.internal.V2Convertor.transCompleteMultipartUpload(V2Convertor.java:96) ~[esdk-obs-java-bundle-3.23.9.1.jar:?]at com.obs.services.internal.service.ObsMultipartObjectService.completeMultipartUploadImpl(ObsMultipartObjectService.java:96) ~[esdk-obs-java-bundle-3.23.9.1.jar:?]at com.obs.services.AbstractMultipartObjectClient.access$400(AbstractMultipartObjectClient.java:39) ~[esdk-obs-java-bundle-3.23.9.1.jar:?]at com.obs.services.AbstractMultipartObjectClient$5.action(AbstractMultipartObjectClient.java:185) ~[esdk-obs-java-bundle-3.23.9.1.jar:?]at com.obs.services.AbstractMultipartObjectClient$5.action(AbstractMultipartObjectClient.java:182) ~[esdk-obs-java-bundle-3.23.9.1.jar:?]at com.obs.services.AbstractClient.doActionWithResult(AbstractClient.java:388) ~[esdk-obs-java-bundle-3.23.9.1.jar:?]... 50 more

2、BUG定位

首先看抛异常的第一条信息,org.apache.xalan.processor.TransformerFactoryImpl,这个类首先看名称,后面带了Impl,一般来说应该是某个接口的实现类,因为这个是引用的jar包里报的错,还是apache的jar包,一般来说不太可能是apache代码写错了,所以很有可能是我们调这个接口的时候,调错实现类了,实际上不应该调apache的这个实现类。

直接来看调用方com.obs.services.internal.xml.OBSXMLBuilder的asString方法:

public String asString() throws TransformerException {TransformerFactory tf = TransformerFactory.newInstance();tf.setAttribute("http://javax.xml.XMLConstants/property/accessExternalDTD", "");tf.setAttribute("http://javax.xml.XMLConstants/property/accessExternalStylesheet", "");Transformer transformer = tf.newTransformer();transformer.setOutputProperty("omit-xml-declaration", "yes");StringWriter writer = new StringWriter();transformer.transform(new DOMSource(this.getDocument()), new StreamResult(writer));return writer.getBuffer().toString().replaceAll("|\r", "");
}

代码里的TransformerFactory是个抽象类,整个方法中也没有指定使用到底用哪个实现类,这个时候就应该想到Java的SPI机制了,打开org.apache.xalan.processor.TransformerFactoryImpl所在Jar包,Jar包里有个文件夹META-INF,里面有个services的文件夹,这里面的文件,就指定了程序会使用TransformerFactory的哪个实现类,如下图:
在这里插入图片描述
打开该文件,文件内容如下:

org.apache.xalan.processor.TransformerFactoryImpl

由于我们的程序里没有相应的SPI配置,所以程序会优先使用org.apache.xalan.processor.TransformerFactoryImpl类

3、BUG修复

知道了问题所在,接下来就是要找到那个正确的类,我们进到TransformerFactory这个类里,由于我用的是IDEA,点类边上的蓝色按钮就可以找到这个类的子类,如下图:
在这里插入图片描述
可以看到同样叫TransformerFactoryImpl名字的,还有com.sun.org.apache.xalan.internal.xsltc.trax包下的类,然后我们就在项目的META-INF的目录下新增services目录(如果没有的话),在该目录下新增文件javax.xml.transform.TransformerFactory,如图:
在这里插入图片描述
文件内容如下:

com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl

再启动服务时,服务就正常了

4、疑惑

眼尖的小伙伴可能会发现,我这个异常是在生产环境抛出来的,难道我之前测试环境没测出来这个问题吗,是的,测试环境当时测的时候没有指定实现类也没有报错,文件也正常上传到了华为云OBS上,但是这个问题发生后,再在测试环境就没法复现这个问题了,所以也没有再深究。


找到问题了,我们在引入OBS的jar包时是这样写的:

<dependency><groupId>com.huaweicloud</groupId><artifactId>esdk-obs-java-bundle</artifactId><version>[3.21.8,)</version>
</dependency>

这种写法会导致使用最新版本的jar包,来看jar包的发布时间:
在这里插入图片描述
我们测试的时候大概是在十月份,十一月、十二月都有过发布,功能启用时间更是在后面,所以我们测试的jar跟生产的jar实际上版本是不一样的,生产是3.23.9.1,而测试是3.23.9,我们将版本指定为3.23.9后查看com.obs.services.internal.xml.OBSXMLBuilder源码,里面并没有使用抽象类TransformerFactory,所以也不会有上面所说的问题。

相关文章:

记一次SPI机制导致的BUG定位【不支持:http://javax.xml.XMLConstants/property/accessExternalDTD】

1、前因 今天在生产环境启用了某个功能&#xff0c;结果发现有个文件上传华为云OBS失败了&#xff0c;报错如下&#xff1a; Caused by: java.lang.IllegalArgumentException: 不支持&#xff1a;http://javax.xml.XMLConstants/property/accessExternalDTDat org.apache.xal…...

Kali如何启动SSH服务并实现无公网ip环境远程连接

文章目录 1. 启动kali ssh 服务2. kali 安装cpolar 内网穿透3. 配置kali ssh公网地址4. 远程连接5. 固定连接SSH公网地址6. SSH固定地址连接测试 简单几步通过[cpolar 内网穿透](cpolar官网-安全的内网穿透工具 | 无需公网ip | 远程访问 | 搭建网站)软件实现ssh 远程连接kali! …...

谷粒商城配置虚拟机

一、创建虚拟机 之前有在VM里面建一个ubuntu的虚拟机&#xff0c;准备拿来直接用&#xff0c;网络设置为NAT模式&#xff0c;查看我的虚拟机是虚拟机&#xff1a;192.168.248.128 主机&#xff1a; 192.168.2.12。可以互相ping通。 二、linux安装docker Docker docker是虚拟…...

Java中文乱码浅析及解决方案

Java中文乱码浅析及解决方案 一、GBK和UTF-8编码方式二、idea和eclipse的默认编码方式三、解码和编码方法四、代码实现编码解码 五、额外知识扩展 一、GBK和UTF-8编码方式 如果采用的是UTF-8的编码方式&#xff0c;那么1个英文字母 占 1个字节&#xff0c;1个中文占3个字节如果…...

【前端基础--3】

文字样式 1.文字颜色 color 取值方式&#xff1a; 英文单词 red green blue十六进制的颜色值 #000000 也可以写为#000&#xff08;如aabbcc可以简写为abc&#xff09;rgb三原色取值 color&#xff1a;rgb(220,32,215) 取值范围都在0~255之间 2.文字大小 font-size …...

Obsidian笔记软件结合cpolar实现安卓移动端远程本地群晖WebDAV数据同步

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

51单片机电子密码锁Proteus仿真+程序+视频+报告

目录 视频 设计分析 系统结构 仿真图 资料内容 资料下载地址&#xff1a;51单片机电子密码锁Proteus仿真程序视频报告 视频 单片机电子密码锁Proteus仿真程序视频 设计分析 (1)能够从键盘中输入密码&#xff0c;并相应地在显示器上显示‘*’&#xff1b; (2)能够判断密码…...

[BSidesCF 2020]Had a bad day

先看url&#xff0c;发现可能有注入 http://655c742e-b427-485c-9e15-20a1e7ef1717.node5.buuoj.cn:81/index.php?categorywoofers 试试能不能查看index.php直接?categoryindex.php不行&#xff0c;试试伪协议 把.php去掉试试 base64解码 <?php$file $_GET[category];…...

[笔记]事务简介-springboot

在Spring Boot中&#xff0c;事务的管理通常通过注解来实现&#xff0c;使得配置变得简单而直观。这种方式与Spring Boot的设计理念一致&#xff0c;即减少显式配置&#xff0c;增加自动配置。以下是如何在Spring Boot项目中应用和管理事务的详细说明&#xff1a; Spring Boot中…...

初识计算机网络 | 计算机网络的发展 | 协议初识

1.计算机网络的发展 “矛盾是普遍存在的&#xff0c;矛盾是事物联系的实质内容和事物发展的根本动力&#xff01;” 计算机在诞生之初&#xff0c;在军事上用来计算导弹的弹道轨迹&#xff01;在发展的过程中&#xff08;商业的推动&#xff0c;国家政策推动&#xff09;&…...

【sgTree】自定义组件:加载el-tree树节点整棵树数据,实现增删改操作。

特性 可以自定义主键、配置选项支持预定义节点图标&#xff1a;folder文件夹|normal普通样式多个提示文本可以自定义支持动态接口增删改节点可以自定义根节点id可以设置最多允许添加的层级深度支持拖拽排序&#xff0c;排序过程还可以针对拖拽的节点深度进行自定义限制支持隐藏…...

vue2面试题:vue组件之间的通信方式有哪些?

vue2面试题&#xff1a;vue组件之间的通信方式有哪些&#xff1f; 回答思路&#xff1a;1.组件通信的目的-->2.组件通信的分类-->3.组件通信的方案1.组件通信的目的2.组件通信的分类3.组件通信的方案&#xff08;1&#xff09;通过props传递数据&#xff08;2&#xff09…...

Pytorch神经网络模型nn.Sequential与nn.Linear

1、定义模型 对于标准深度学习模型&#xff0c;我们可以使用框架的预定义好的层。这使我们只需关注使用哪些层来构造模型&#xff0c;而不必关注层的实现细节。 我们首先定义一个模型变量net&#xff0c;它是一个Sequential类的实例。 Sequential类将多个层串联在一起。 当给…...

C++-gdb调试常用功能

文章目录 启动gdb运行程序设置断点运行控制查看源码查看信息查看变量线程相关 gdb调试常用功能如下&#xff0c;其中bin为要调试的程序&#xff0c;arg为参数 启动gdb 启动调试 gdb bin带参数启动 gdb --args bin arg1 arg2so预加载LD_PRELOAD/path/to/lib.so && gdb …...

快速上手的AI工具-文心一言辅助学习

前言 大家好晚上好&#xff0c;现在AI技术的发展&#xff0c;它已经渗透到我们生活的各个层面。对于普通人来说&#xff0c;理解并有效利用AI技术不仅能增强个人竞争力&#xff0c;还能在日常生活中带来便利。无论是提高工作效率&#xff0c;还是优化日常任务&#xff0c;AI工…...

Boost 适用 filesystem 库,statx 函数无法找到引用问题的解决方案。

1、boost 高版本使用了 statx 函数&#xff0c;这个函数是在 Linux 内核版本 4.11 之后引入的。 所以&#xff1a;可以升级 Linux 内核版本到4.11之后即可。 2、降低 boost 库版本到 1.70 以下 3、正确的路&#xff0c;改 boost 的编译代码 先看这个&#xff1a; Filesyste…...

MyBatis中一级缓存是什么?SqlSession一级缓存失效的原因?如何理解一级缓存?

一级缓存是SqlSession级别的&#xff0c;通过同一个SqlSession查询的数据会被缓存&#xff0c;下次查询相同的数据&#xff0c;就 会从缓存中直接获取&#xff0c;不会从数据库重新访问 使一级缓存失效的四种情况&#xff1a; 1) 不同的SqlSession对应不同的一级缓存 2) 同一…...

项目解决方案:多地医馆的高清视频监控接入汇聚联网

目 录 一、背景 二、建设目标及需求 1.建设目标 2.现状分析 3.需求分析 三、方案设计 1.设计依据 2.设计原则 3.方案设计 3.1 方案描述 3.2 组网说明 四、产品介绍 1.视频监控综合资源管理平台介绍 2.视频录像服务器和存储 2.1概述 2.2存储设计 …...

【前端基础--2】

选择器优先级 style标签中&#xff1a; .text{color: pink;}div{color: red;}#box{color: skyblue;} body标签中&#xff1a; <div class"text" id"box">猜猜我是什么颜色的</div> 运行结果&#xff1a; 选择器优先级权重&#xff1a; id选…...

【GitHub项目推荐--提取文字】【转载】

提取视频中的字幕 这个开源项目是提取视频中字幕的开源项目&#xff0c;提取视频中的关键帧&#xff0c;检测视频帧中文本的所在位置&#xff0c;识别视频帧中文本的内容。 不知道大家有没有做笔记的习惯&#xff0c;这个开源项目就很方便的把你一个视频中的字幕提取出来&…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

虚拟电厂发展三大趋势:市场化、技术主导、车网互联

市场化&#xff1a;从政策驱动到多元盈利 政策全面赋能 2025年4月&#xff0c;国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》&#xff0c;首次明确虚拟电厂为“独立市场主体”&#xff0c;提出硬性目标&#xff1a;2027年全国调节能力≥2000万千瓦&#xff0…...