maven打包顺序与jvm类加载顺序
背景:一次dev测试过程中,发现代码中关于jsr303的校验失效,校验类如下,会报一个莫名其妙的运行时错误;遂进行排查。
import javax.validation.constraints.NotBlank;@Data
@Accessors(chain = true)
public class Demo {@NotBlankprivate String fieldOne;@NotBlankprivate String fieldTwo;
}
排查结果:有经验的同学在,报错信息中就可以大致推断出类冲突了,或者存在同名类覆盖了。最终结果,代码中果然有多个@NotBlank注解,且代码路径都是javax.validation.constraints.NotBlank;正确的注解是2中的,1中是错误的。1中的注解,没有groups信息,会导致报错。jsr303在校验的过程中会去获取注解上的groups信息的;没接触过jsr303的同学,可以移步@Validate注解使用原理详解。

问题解决:排查至此,问题已经可以解决了,方法一:可以通过排包,把1中的包排掉;方法二:
对于使用javax.validation.constraints.NotBlank的类,使用org.hibernate.validator.constraints.NotBlank的替换(这个类,路径是唯一的)
你以为到此就结束了吗,没有,如果到此结束,这篇文章的标题可能需要换一个了。整个排查过程中有一些想不通的点,需要在梳理下。
覆盖的注解分别来自如下2个jar包,但是这2个依赖在线上也存在;并且线上没有覆盖的问题,覆盖问题仅仅存在于测试环境。上图中1中的注解的jar包
<dependency><groupId>net.sf.oval</groupId><artifactId>oval</artifactId>
</dependency>上图中2中的注解来自jar包,
<dependency><groupId>javax.validation</groupId><artifactId>validation-api</artifactId></dependency>现在有充分的理由怀疑,jvm的类加载顺序,导致了这2个jar包的同名类,在线上和测试环境表现有差异。线上jvm加载的是2中的类,测试环境是1中的类。
本地分别启动master代码,测试环境代码,启动参数加上-XX:+TraceClassLoading,输出类加载信息
master代码输出如下:
[Loaded javax.validation.constraints.NotBlank from file:/D:/maven_jar/javax/validation/validation-api/2.0.1.Final/validation-api-2.0.1.Final.jar]
测试代码输出如下:
[Loaded javax.validation.constraints.NotBlank from file:/D:/maven_jar/net/sf/oval/oval/1.90/oval-1.90.jar]
根据类加载信息,石锤了线上用的是2中的jar包,测试环境用的是1中的jar包。
新的问题又来了,这2个jar包master代码和dev代码都有,为啥会导致jvm的加载顺序不一致呢?是什么影响了呢?
再次review dev代码改动,发现有人改动了pom,改变了2中jar包的依赖顺序(本来jar包赖在A依赖,现在jar包来自B依赖)。合理推测一波,maven的打包出来的lib下面的jar包集合,顺序影响了jvm的类加载顺序。
知识点:其实idea支持,调整jvm的jar包加载顺序的,上界面(经历过非maven项目的小伙伴可能会想起来这个)。通过这个页面可以看到,master代码中2中的jar包在1的jar包之前,在dev环境中,1的jar包在2的jar包之前。

经过测试,此处的jar包顺序和pom文件中,声明依赖的顺序有关。先申明的依赖(包括依赖传递待过来的依赖)会优先被打包,在jvm中也会优先加载。传送门:IDEA使用maven进行多模块项目打包并梳理正确的打包顺序
结论:
maven项目中,lib目录下jar包的打包顺序和pom文件中的依赖的声明顺序一致,先声明的依赖相关的jar包先打包。
jvm 的jar包加载顺序和maven 的jar包打包顺序一致
idea可以看到和改动,jvm 的加载jar包的顺序
JVM的类加载顺序和jar包顺序相关,一个全路径类被加载后,后续在有相同路径的类,便不会被加载
参考资料:IDEA使用maven进行多模块项目打包并梳理正确的打包顺序
相关文章:
maven打包顺序与jvm类加载顺序
背景:一次dev测试过程中,发现代码中关于jsr303的校验失效,校验类如下,会报一个莫名其妙的运行时错误;遂进行排查。import javax.validation.constraints.NotBlank;Data Accessors(chain true) public class Demo {Not…...
④ 链表
24. 两两交换链表中的节点 题目链接:https://leetcode.cn/problems/swap-nodes-in-pairs/ 注意点: 遍历链表的时候什么时候截止(避免空指针异常或无限死循环的问题)? 节点数量为偶数或链表为空时,cur.ne…...
小孩扁桃体肿大3度能自愈吗?6岁小孩扁桃体肥大怎么治效果好?
12月7日,四川眉山市民唐先生说,他刚出生的儿子在妇产医院分娩中心住了20天后感染了败血症。据唐先生介绍,哈子出院时各项指标正常。他在分娩中心住了半个月左右,孩子喝牛奶很生气,第二天就开始发烧了。同一天ÿ…...
【C++提高编程】C++全栈体系(二十二)
C提高编程 第三章 STL - 常用容器 五、stack容器 1. stack 基本概念 概念:stack是一种先进后出(First In Last Out,FILO)的数据结构,它只有一个出口 栈中只有顶端的元素才可以被外界使用,因此栈不允许有遍历行为 栈中进入数据称为 — 入…...
linux系统编程2--网络编程socket知识
在linux系统编程中网络编程是使用socket(套接字),socket这个词可以表示很多概念:在TCP/IP协议中,“IP地址TCP或UDP端口号”唯一标识网络通讯中的一个进程,“IP地址端口号”就称为socket。在TCP协议中&#…...
Python-__repr__、__hash__和__eq__方法,split()、join()、yield()和append()函数
1.__repr__方法程序1class Python:passa Python() print(a) print(a.__repr__())结果<__main__.Python object at 0x0000023B82185FD0> <__main__.Python object at 0x0000023B82185FD0>默认情况下,我们得到的信息只会是“类名object at内存地址”程序…...
【安卓开发】安卓广播机制
读书笔记系列(第一行代码) 5.1 广播机制简介 标准广播:完全异步执行,广播发出后,所有广播接收器几乎都同一时刻收到这条广播(无法被截断)有序广播:同步执行,广播发出后…...
移动WEB开发四、rem布局
零、文章目录 文章地址 个人博客-CSDN地址:https://blog.csdn.net/liyou123456789个人博客-GiteePages:https://bluecusliyou.gitee.io/techlearn 代码仓库地址 Gitee:https://gitee.com/bluecusliyou/TechLearnGithub:https:…...
request.getURL()和request.getURI() 以及通过request获得路径相关大全
request.getURL()和request.getURI() 如果我的请求是:http://localhost:8080/ServletTest/servlet/Hello request.getRequestURI() 返回值类似:/ServletTest/servlet/Hello request.getRequestURL() 返回值类似:http://localhost:8080/Servle…...
java网络编程-nio学习:阻塞和非阻塞
一、阻塞 阻塞模式下,相关方法都会导致线程暂停 ServerSocketChannel.accept 会在没有连接建立时让线程暂停 SocketChannel.read 会在没有数据可读时让线程暂停 阻塞的表现其实就是线程暂停了,暂停期间不会占用 cpu,但线程相当于闲置 单线…...
JVM-JMM内存模型(happens-before、volatile)
前言 由于计算机的存储设备与处理器的运算速度有几个数量级的差距所以现代计算机系统都不得不加入一层读写速度尽可能接近处理器运算速度的高速缓存(Cache)来作为内存与处理器之间的缓冲。 将运算需要使用到的数据复制到缓存中,让运算能快速进行,当运算…...
算法leetcode|37. 解数独(rust重拳出击)
文章目录37. 解数独:样例 1:提示:分析:题解:rustgoccpythonjava37. 解数独: 编写一个程序,通过填充空格来解决数独问题。 数独的解法需 遵循如下规则: 数字 1-9 在每一行只能出现…...
SpringBoot整合Dubbo
目录1、dubbo简介2、dubbo解决了什么问题3、环境准备4、项目搭建5、总结springboot整合feign可参考我另外一篇文章SpringBoot集成Feign 1、dubbo简介 Apache Dubbo 最初在 2008 年由 Alibaba 捐献开源,很快成为了国内开源服务框架选型的事实标准框架 ,…...
[软件工程导论(第六版)]第9章 面向对象方法学引论(课后习题详解)
文章目录1. 什么是面向对象方法学?它有哪些优点?2. 什么是“对象”?它与传统的数据有何异同?3. 什么是“类”?4. 什么是“继承”?5. 什么是模型?开发软件为何要建模?6. 什么是对象模…...
光学分辨率光声显微镜中基于深度学习的运动校正算法
在这项研究中,我们提出了一种基于深度学习的方法来校正光学分辨率光声显微镜 (OR-PAM) 中的运动伪影。该方法是一种卷积神经网络,它从具有运动伪影的输入原始数据建立端到端映射,以输出校正后的图像。首先,我们进行了仿真研究&…...
浅谈UG二次开发中使用的FindObject
一般我们在业务逻辑里想查找一个Object的时候,会调用FindObject、GetObject、NxObjectManager.Get,不管是上述哪种实现,都是在内存中找东西,找到了就返回对象,否则返回null,但不会触发加载。 这里我分别从建…...
贪心原理及刷题
更新中 概念 使用贪心需要满足,上一步的局部最优解能推出这一步的局部最优解,直到得到全局最优解 而dp这一步的局部最优,不一定来源上一步的局部最优,而可能与更早的解有关,同时dp转移方程的推导也比较复杂 122. 买卖股票的最佳时机 II - 力扣(LeetCode) 这道题是典…...
2023赏金计划:Coremail SRC漏洞征集与样本奖励火热进行中
赏金活动一:Coremail SRC漏洞奖励计划 01 活动背景 2023年1月,Coremail安全应急响应中心(Coremail SRC)正式上线启用,面向公众收集安全漏洞信息与安全情报。Coremail SRC旨在联合众多安全专家、白帽子研究员共同发现…...
简记:清理指定后缀名文件的 powerhsell 小脚本
清理指定后缀名文件的 powerhsell 小脚本jcLee95:https://blog.csdn.net/qq_28550263?spm1001.2101.3001.5343 邮箱 :291148484163.com 本文地址:https://blog.csdn.net/qq_28550263/article/details/129121074 1.介绍 相关工具代码 2.目…...
问题记录:mac系统偏好设置不展示mysql
Mac新系统升级(10.14.5)后未从appstore下载的软件在安装时会提示安装包已损坏之类的东东,这是因为没有打开“设置”—“安全与隐私”中的“任何来源”造成的,可是升级后的10.14.5却没有这个选项。 那么macOS 10.14.5以上允许任何…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...
Qemu arm操作系统开发环境
使用qemu虚拟arm硬件比较合适。 步骤如下: 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载,下载地址:https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...
uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...
node.js的初步学习
那什么是node.js呢? 和JavaScript又是什么关系呢? node.js 提供了 JavaScript的运行环境。当JavaScript作为后端开发语言来说, 需要在node.js的环境上进行当JavaScript作为前端开发语言来说,需要在浏览器的环境上进行 Node.js 可…...
