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

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类加载顺序

背景&#xff1a;一次dev测试过程中&#xff0c;发现代码中关于jsr303的校验失效&#xff0c;校验类如下&#xff0c;会报一个莫名其妙的运行时错误&#xff1b;遂进行排查。import javax.validation.constraints.NotBlank;Data Accessors(chain true) public class Demo {Not…...

④ 链表

24. 两两交换链表中的节点 题目链接&#xff1a;https://leetcode.cn/problems/swap-nodes-in-pairs/ 注意点&#xff1a; 遍历链表的时候什么时候截止&#xff08;避免空指针异常或无限死循环的问题&#xff09;&#xff1f; 节点数量为偶数或链表为空时&#xff0c;cur.ne…...

小孩扁桃体肿大3度能自愈吗?6岁小孩扁桃体肥大怎么治效果好?

12月7日&#xff0c;四川眉山市民唐先生说&#xff0c;他刚出生的儿子在妇产医院分娩中心住了20天后感染了败血症。据唐先生介绍&#xff0c;哈子出院时各项指标正常。他在分娩中心住了半个月左右&#xff0c;孩子喝牛奶很生气&#xff0c;第二天就开始发烧了。同一天&#xff…...

【C++提高编程】C++全栈体系(二十二)

C提高编程 第三章 STL - 常用容器 五、stack容器 1. stack 基本概念 概念&#xff1a;stack是一种先进后出(First In Last Out,FILO)的数据结构&#xff0c;它只有一个出口 栈中只有顶端的元素才可以被外界使用&#xff0c;因此栈不允许有遍历行为 栈中进入数据称为 — 入…...

linux系统编程2--网络编程socket知识

在linux系统编程中网络编程是使用socket&#xff08;套接字&#xff09;&#xff0c;socket这个词可以表示很多概念&#xff1a;在TCP/IP协议中&#xff0c;“IP地址TCP或UDP端口号”唯一标识网络通讯中的一个进程&#xff0c;“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>默认情况下&#xff0c;我们得到的信息只会是“类名object at内存地址”程序…...

【安卓开发】安卓广播机制

读书笔记系列&#xff08;第一行代码&#xff09; 5.1 广播机制简介 标准广播&#xff1a;完全异步执行&#xff0c;广播发出后&#xff0c;所有广播接收器几乎都同一时刻收到这条广播&#xff08;无法被截断&#xff09;有序广播&#xff1a;同步执行&#xff0c;广播发出后…...

移动WEB开发四、rem布局

零、文章目录 文章地址 个人博客-CSDN地址&#xff1a;https://blog.csdn.net/liyou123456789个人博客-GiteePages&#xff1a;https://bluecusliyou.gitee.io/techlearn 代码仓库地址 Gitee&#xff1a;https://gitee.com/bluecusliyou/TechLearnGithub&#xff1a;https:…...

request.getURL()和request.getURI() 以及通过request获得路径相关大全

request.getURL()和request.getURI() 如果我的请求是&#xff1a;http://localhost:8080/ServletTest/servlet/Hello request.getRequestURI() 返回值类似&#xff1a;/ServletTest/servlet/Hello request.getRequestURL() 返回值类似&#xff1a;http://localhost:8080/Servle…...

java网络编程-nio学习:阻塞和非阻塞

一、阻塞 阻塞模式下&#xff0c;相关方法都会导致线程暂停 ServerSocketChannel.accept 会在没有连接建立时让线程暂停 SocketChannel.read 会在没有数据可读时让线程暂停 阻塞的表现其实就是线程暂停了&#xff0c;暂停期间不会占用 cpu&#xff0c;但线程相当于闲置 单线…...

JVM-JMM内存模型(happens-before、volatile)

前言 由于计算机的存储设备与处理器的运算速度有几个数量级的差距所以现代计算机系统都不得不加入一层读写速度尽可能接近处理器运算速度的高速缓存(Cache)来作为内存与处理器之间的缓冲。 将运算需要使用到的数据复制到缓存中&#xff0c;让运算能快速进行&#xff0c;当运算…...

算法leetcode|37. 解数独(rust重拳出击)

文章目录37. 解数独&#xff1a;样例 1&#xff1a;提示&#xff1a;分析&#xff1a;题解&#xff1a;rustgoccpythonjava37. 解数独&#xff1a; 编写一个程序&#xff0c;通过填充空格来解决数独问题。 数独的解法需 遵循如下规则&#xff1a; 数字 1-9 在每一行只能出现…...

SpringBoot整合Dubbo

目录1、dubbo简介2、dubbo解决了什么问题3、环境准备4、项目搭建5、总结springboot整合feign可参考我另外一篇文章SpringBoot集成Feign 1、dubbo简介 Apache Dubbo 最初在 2008 年由 Alibaba 捐献开源&#xff0c;很快成为了国内开源服务框架选型的事实标准框架 &#xff0c;…...

[软件工程导论(第六版)]第9章 面向对象方法学引论(课后习题详解)

文章目录1. 什么是面向对象方法学&#xff1f;它有哪些优点&#xff1f;2. 什么是“对象”&#xff1f;它与传统的数据有何异同&#xff1f;3. 什么是“类”&#xff1f;4. 什么是“继承”&#xff1f;5. 什么是模型&#xff1f;开发软件为何要建模&#xff1f;6. 什么是对象模…...

光学分辨率光声显微镜中基于深度学习的运动校正算法

在这项研究中&#xff0c;我们提出了一种基于深度学习的方法来校正光学分辨率光声显微镜 (OR-PAM) 中的运动伪影。该方法是一种卷积神经网络&#xff0c;它从具有运动伪影的输入原始数据建立端到端映射&#xff0c;以输出校正后的图像。首先&#xff0c;我们进行了仿真研究&…...

浅谈UG二次开发中使用的FindObject

一般我们在业务逻辑里想查找一个Object的时候&#xff0c;会调用FindObject、GetObject、NxObjectManager.Get&#xff0c;不管是上述哪种实现&#xff0c;都是在内存中找东西&#xff0c;找到了就返回对象&#xff0c;否则返回null&#xff0c;但不会触发加载。 这里我分别从建…...

贪心原理及刷题

更新中 概念 使用贪心需要满足,上一步的局部最优解能推出这一步的局部最优解,直到得到全局最优解 而dp这一步的局部最优,不一定来源上一步的局部最优,而可能与更早的解有关,同时dp转移方程的推导也比较复杂 122. 买卖股票的最佳时机 II - 力扣(LeetCode) 这道题是典…...

2023赏金计划:Coremail SRC漏洞征集与样本奖励火热进行中

赏金活动一&#xff1a;Coremail SRC漏洞奖励计划 01 活动背景 2023年1月&#xff0c;Coremail安全应急响应中心&#xff08;Coremail SRC&#xff09;正式上线启用&#xff0c;面向公众收集安全漏洞信息与安全情报。Coremail SRC旨在联合众多安全专家、白帽子研究员共同发现…...

简记:清理指定后缀名文件的 powerhsell 小脚本

清理指定后缀名文件的 powerhsell 小脚本jcLee95&#xff1a;https://blog.csdn.net/qq_28550263?spm1001.2101.3001.5343 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/details/129121074 1.介绍 相关工具代码 2.目…...

问题记录:mac系统偏好设置不展示mysql

Mac新系统升级&#xff08;10.14.5&#xff09;后未从appstore下载的软件在安装时会提示安装包已损坏之类的东东&#xff0c;这是因为没有打开“设置”—“安全与隐私”中的“任何来源”造成的&#xff0c;可是升级后的10.14.5却没有这个选项。 那么macOS 10.14.5以上允许任何…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

SkyWalking 10.2.0 SWCK 配置过程

SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外&#xff0c;K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案&#xff0c;全安装在K8S群集中。 具体可参…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

&#x1f680; C extern 关键字深度解析&#xff1a;跨文件编程的终极指南 &#x1f4c5; 更新时间&#xff1a;2025年6月5日 &#x1f3f7;️ 标签&#xff1a;C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言&#x1f525;一、extern 是什么&#xff1f;&…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...

深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏

一、引言 在深度学习中&#xff0c;我们训练出的神经网络往往非常庞大&#xff08;比如像 ResNet、YOLOv8、Vision Transformer&#xff09;&#xff0c;虽然精度很高&#xff0c;但“太重”了&#xff0c;运行起来很慢&#xff0c;占用内存大&#xff0c;不适合部署到手机、摄…...

前端调试HTTP状态码

1xx&#xff08;信息类状态码&#xff09; 这类状态码表示临时响应&#xff0c;需要客户端继续处理请求。 100 Continue 服务器已收到请求的初始部分&#xff0c;客户端应继续发送剩余部分。 2xx&#xff08;成功类状态码&#xff09; 表示请求已成功被服务器接收、理解并处…...