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

news2024/9/28 23:37:38

1、前因

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

Caused by: java.lang.IllegalArgumentException: 不支持:http://javax.xml.XMLConstants/property/accessExternalDTD
        at 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,所以也不会有上面所说的问题。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ctfshow信息收集(web1-web20)

目录 web1 web2 web3 web4 web5 web6 web7 web9 web10 web11 web14 web15 web16 web17 web18 web19 web20 web1 根据提示的孩子开发的时候注释没有被及时删除 web2 js原因无法查看源代码 第一种方法 在url前加入 view-source&#xff1a; 会显示页面源代…

获取双异步返回值时,如何保证主线程不阻塞?

目录 一、前情提要二、JDK8的CompletableFuture1、ForkJoinPool2、从ForkJoinPool和ThreadPoolExecutor探索CompletableFuture和Future的区别 三、通过CompletableFuture优化 “通过Future获取异步返回值”1、通过Future获取异步返回值关键代码&#xff08;1&#xff09;将异步…

springboot-mybatis项目

一、后端开发环境搭建 1、File->New->Projet 2选择 Spring Initializr &#xff0c;然后选择默认的 url 点击next 3勾选Spring Web、SQL模板&#xff0c;next 4点击finish&#xff0c;搭建完成 二 数据库 1 新建数据库 2 执行sql建表 SET NAMES utf8mb4; SET FOREIGN…

嵌入式学习-C++-Day2

嵌入式学习-CDay2 一、思维导图 二、作业 1.封装一个矩形类(Rect)&#xff0c;拥有私有属性:宽度(width)、高度(height)&#xff0c;定义公有成员函数:初始化函数:void init(int w, int h) 更改宽度的函数:set_w(int w) 更改高度的函数:set_h(int h) 输出该矩形的周长和面积函…

ActiveMQ|01-ClassicArtemis功能介绍

接上篇-MQ消息队列主流消息服务规范及代表产品&#xff0c;ActiveMQ就是基于JMS消息服务规范的消息中间件组件&#xff0c;主要应用在分布式系统架构中&#xff0c;帮助构建高可用、 高性能、可伸缩的企业级面向消息服务的系统 本文速览&#xff1a; JMS对象模型ActiveMQ的功…

elementplus Dialog 对话框设置距离页面顶部的距离

默认为 15vh&#xff0c;当弹窗过于高的时候&#xff0c;这个距离其实是不合适的 <el-dialogv-model"dialogVisible"title"Tips"width"30%":before-close"handleClose"top"6vh"><span>This is a message</s…

LeetCode刷题---旋转链表

解题思路: 首先创建辅助节点cur遍历指向链表最后一个节点&#xff0c;并将cur的下一个节点指向head头节点&#xff0c;形成闭环&#xff0c;并且在遍历的过程中计算链表的长度n。 n-k表示当前节点&#xff08;当前节点指向未反转节点的最后一个节点&#xff09;到反转后的链表的…

输入框限制输入两位小数 输入金额限制 双向绑定输入框能继续输入但是变量的数据不变解决方案 input 保留两位小数

移动端项目 需求是 输入框只能输入1000以内的数字保留两位小数 开发中发现 用vue开发双向绑定 不管是用value还是v-model 在输入时用input监听输入框变化 校验是否匹配 当不匹配是修改绑定的变量 inputValue时 打印inputValue符合预期 但是input输入框中还是原来输入的值 没有…

对话框与多窗体设计 —— 自定义对话框及其调用

3.2 自定义对话框及其调用3.3 Splash与登录窗口 3.2 自定义对话框及其调用 在一个应用程序设计中&#xff0c;为了实现一些特定的功能&#xff0c;必 须设计自定义对话框。自定义对话框的设计一般从 QDialog继承&#xff0c;并且可以采用UI设计器可视化地设计对 话框。对话框的…

发送消息提醒学习使用

效果图 数据库表及实体模型参考 创建消息事件模型 public class SystemMsgSendEvent implements DomainEvent {private String eventId;//事件idprivate ExecutePoint executePoint;//执行方式 事务提交后当前线程private OperateInfo operateInfo;//操作信息private String …

【AIGC】Diffusers:AutoPipeline自动化扩散生图管道

前言 &#x1f917; 扩散器能够完成许多不同的任务&#xff0c;并且您通常可以将相同的预训练权重用于多个任务&#xff0c;例如文本到图像、图像到图像和修复。但是&#xff0c;如果您不熟悉库和扩散模型&#xff0c;可能很难知道将哪个管道用于任务。例如&#xff0c;如果您…

【博客搭建记录贴】day4_Hexo基本操作,添加草稿并发布

目录 1.将项目导入到开发环境1.1 先把项目导入到IDEA中1.2 确认IDEA中服务器启动正常 2.Hexo基本操作: 添加草稿并发布2.1 生成一个草稿文件2.2 在页面上查看草稿3.3 将草稿正式发布 1.将项目导入到开发环境 我本地已经安装了 IntelliJ IDEA&#xff08;版本&#xff1a;社区版…

web蓝桥杯真题--13、水果摆盘

背景介绍 目前 CSS3 中新增的 Flex 弹性布局已经成为前端页面布局的首选方式&#xff0c;这次试题将利用 Flex 实现经典布局效果。 准备步骤 在开始答题前&#xff0c;你需要在线上环境终端中键入以下命令&#xff0c;下载并解压所提供的文件。 wget https://labfile.oss.a…

某马头条——day11+day12

实时计算和定时计算 流式计算 kafkaStream 入门案例 导入依赖 <dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-streams</artifactId><exclusions><exclusion><artifactId>connect-json</artifactId&…

仿真机器人-深度学习CV和激光雷达感知(项目2)day04【简单例程】

文章目录 前言简单例程运行小海龟仿真启动节点查看计算图发布 Topic调用 Serviece 用 Python 发布和接收 Topic创建工作空间创建功能包&#xff0c;编译编写 Topic Publisher 节点编写 Topic Subscriber 节点运行节点 自定义消息类型用 Python 注册和调用 Serviece新建功能包在…

更高效的大模型调优方法,华盛顿大学推出“代理调优”

随着ChatGPT等生成式AI产品朝着多模态发展&#xff0c;基础模型的参数越来越高&#xff0c;想进行权重调优需要耗费大量时间和AI算力。 为了提升模型的调优效率&#xff0c;华盛顿大学和艾伦AI实验室的研究人员推出了全新方法——Proxy Tuning&#xff08;代理调优&#xff09…

YOLOv7全网独家首发:Powerful-IoU更好、更快的收敛IoU,效果秒杀CIoU、GIoU等 | 2024年最新IoU

💡💡💡本文独家改进:Powerful-IoU更好、更快的收敛IoU,是一种结合了目标尺寸自适应惩罚因子和基于锚框质量的梯度调节函数的损失函数 💡💡💡MS COCO和PASCAL VOC数据集实现涨点 收录 YOLOv7原创自研 https://blog.csdn.net/m0_63774211/category_12511937.htm…

arcgis 线要素shp数据处理

回顾 上篇写了arcgis 点shp数据处理之少数点和批量点坐标如何生成点要素&#xff0c;这个可能在做一些设计及查询中需要做的第一步。那么今天将对如何点集转线、线要素编辑数据处理做一记录。 一、工具 arcToolbox工具箱、编辑器 二、操作方法 1.点集转线 还是用上篇处理成…

解决软件找不到msvcp120.dll的五种方法,快速修复msvcp120.dll文件丢失方法

msvcp120.dll 是一个动态链接库文件&#xff0c;它是 Microsoft Visual C 2013 的一个部分&#xff0c;具体来说是 Microsoft Visual C Redistributable Package 的一部分。这个文件包含了微软的 C 运行时库&#xff08;CRT&#xff09;&#xff0c;特别是 C 标准库的部分&…

一、Lamdba 表达式与函数式接口(最终版)

一、Lamdba 表达式与函数式接口 1.1 Lamdba 表达式与函数式接口 1.1.1 Lambda 表达式概述 Lambda 表达式是 Java 8 引入的一个新特性Lambda 表达式可以被视为匿名函数允许在需要函数的地方以更简洁的方法定义功能Lambda 表达式可以完成简洁的函数定义Stream API 中大量使用了…