升级包版本之后Reflections反射包在springboot jar环境下扫描不到class排查过程记录

📢📢📢📣📣📣
哈喽!大家好,我是「奇点」,江湖人称 singularity。刚工作几年,想和大家一同进步🤝🤝
一位上进心十足的【Java ToB端大厂领域博主】!😜😜😜
喜欢java和python,平时比较懒,能用程序解决的坚决不手动解决😜😜😜

✨ 如果有对【java】感兴趣的【小可爱】,欢迎关注我

❤️❤️❤️感谢各位大可爱小可爱!❤️❤️❤️
————————————————

如果觉得本文对你有帮助,欢迎点赞,欢迎关注我,如果有补充欢迎评论交流,我将努力创作更多更好的文章。

今天集团将大家使用的三方包的版本进行了升级,其中涉及反射的Reflection的包,Reflections工具的时候(Jar包的版本是org.reflections:reflections:0.10.2),发现在IntelliJ IDEA中运行是能正常扫描出Class对象,但是部署在测试环境或者本地以Jar报运行时,扫描不出来,所以Debug了Reflections源码。

下面是创建Reflection对象的写法,这个在0.9.x版本的时候是没问题的,但是升级到0.10之后就有问题了,找了好半天才解决问题,这里记录一下解决问题的心得和过程,供大家参考。

 点进去最终会调用这个方法来初始化配置

public static ConfigurationBuilder build(Object... params) {final ConfigurationBuilder builder = new ConfigurationBuilder();// flattenList<Object> parameters = new ArrayList<>();for (Object param : params) {if (param.getClass().isArray()) { for (Object p : (Object[]) param) parameters.add(p); }else if (param instanceof Iterable) { for (Object p : (Iterable) param) parameters.add(p); }else parameters.add(param);}ClassLoader[] loaders = Stream.of(params).filter(p -> p instanceof ClassLoader).distinct().toArray(ClassLoader[]::new);if (loaders.length != 0) { builder.addClassLoaders(loaders); }FilterBuilder inputsFilter = new FilterBuilder();builder.filterInputsBy(inputsFilter);for (Object param : parameters) {if (param instanceof String && !((String) param).isEmpty()) {builder.forPackage((String) param, loaders);inputsFilter.includePackage((String) param);} else if (param instanceof Class && !Scanner.class.isAssignableFrom((Class) param)) {builder.addUrls(ClasspathHelper.forClass((Class) param, loaders));inputsFilter.includePackage(((Class) param).getPackage().getName());} else if (param instanceof URL) {builder.addUrls((URL) param);} else if (param instanceof Scanner) {builder.addScanners((Scanner) param);} else if (param instanceof Class && Scanner.class.isAssignableFrom((Class) param)) {try { builder.addScanners(((Class<Scanner>) param).getDeclaredConstructor().newInstance()); }catch (Exception e) { throw new RuntimeException(e); }} else if (param instanceof Predicate) {builder.filterInputsBy((Predicate<String>) param);} else throw new ReflectionsException("could not use param '" + param + "'");}if (builder.getUrls().isEmpty()) {// scan all classpath if no urls provided todo avoidbuilder.addUrls(ClasspathHelper.forClassLoader(loaders));}return builder;}

在For循环中第一个if,如果是String类型的参数,就会设置package,然后会设置filter,问题就出现在这里。这种简写方式,filter是和包名一样的。在本地IDEA中,所有文件都是在out目录下,文件的目录是正常包名开头,如下格式

com/jay/userinterface/authority/model/dto/ProductVO.class

但是如果是以Jar包运行的方式,因为SpringBoot 2.x版本打包时会做一些处理(加一些启动类),导致文件结构会发生变化(读者可以解压一个SpringBoot的Jar包看看实际结构)。这种情况下,获取文件的名称是如下格式

在扫描过程中,这些文件都过不了Filter的校验。

大致过程就是在Reflections类中scan()方法,对每个文件都会根据Filter过滤下,这个Filter就是一个正则表达式的匹配,表达式就是com/jay/userinterface/*,以Jar包方式运行的话,所有文件都会被过滤掉,扫描结果就为空。
 

解决方案

使用另外一种写法,自己构造ReflectionsConfiguration,手动设置Filter

Reflections reflections = new Reflections(new ConfigurationBuilder().forPackages(packageName).filterInputsBy(new FilterBuilder().includePackage("BOOT-INF.classes." + packageName)).setScanners(Scanners.MethodsAnnotated));

我这里面是直接加了前缀,每个文件在Jar包中的实际路径,和Springboot打包后文件格式有关,Springboot 1.x版本应该是不用改的。

也可以通过FilterBuilder的includePattern()方法来直接写正则表达式,兼容IDEA运行和Jar包运行的方式。

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

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

相关文章

LeetCode 1 两数之和

题目描述 链接&#xff1a;https://leetcode.cn/problems/two-sum/?envTypefeatured-list&envId2ckc81c?envTypefeatured-list&envId2ckc81c 难度&#xff1a;简单 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 targ…

Linux system函数返回值

1、语法 #include <stdlib.h>int system(const char *command); 2、函数说明 system()会调用fork()产生子进程&#xff0c;由子进程来调用/bin/sh -c command来执行参数command字符串所代表的命令&#xff0c;此命令执行完后随即返回原调用的进程。 command命令执行完成…

SQL RDBMS 概念

SQL RDBMS 概念 RDBMS是关系数据库管理系统(Relational Database Management System)的缩写。 RDBMS是SQL的基础&#xff0c;也是所有现代数据库系统(如MS SQL Server、IBMDB2、Oracle、MySQL和MicrosoftAccess)的基础。 关系数据库管理系统(Relational Database Management Sy…

python树状打印项目路径

学习这个的需求来自于&#xff0c;我想把项目架构告诉gpt问问它&#xff0c;然后不太会打印项目架构&#x1f602; 联想到Linux的tree指令 import osclass DirectoryTree:def __init__(self, path):self.path pathdef print_tree(self, methoddefault):if method default:sel…

卡顿分析与布局优化

卡顿分析与布局优化 大多数用户感知到的卡顿等性能问题的最主要根源都是因为渲染性能。Android系统每隔大概16.6ms发出VSYNC信 号&#xff0c;触发对UI进行渲染&#xff0c;如果每次渲染都成功&#xff0c;这样就能够达到流畅的画面所需要的60fps&#xff0c;为了能够实现60fp…

LabVIEW生产者消费者架构

LabVIEW生产者消费者架构 生产者/消费者模式可以轻松地同时处理多个进程&#xff0c;同时还能以不同速率迭代。 缓冲通信 当多个进程以不同速度运行时&#xff0c;就适合采用进程间缓冲通信。有了足够大的缓冲区后&#xff0c;生产者循环可以以快于消费者循环的速度运行&…

c语言练习89:链表的使用

链表的使用 虽然有这么多的链表的结构&#xff0c;但是我们实际中最常⽤还是两种结构&#xff1a; 单链表 和 双向带头循环链表 1. ⽆头单向⾮循环链表&#xff1a;结构简单&#xff0c;⼀般不会单独⽤来存数据。实际中更多是作为其他数据结 构的⼦结构&#xff0c;如哈希桶、…

在vs code中创建一个名为 “django_env“ 的虚拟环境报错?!以下方法可以解决

# vs code 终端窗口中运行&#xff1a; mkvirtualenv django_env # 拓展&#xff1a; mkvirtualenv django_env 是一个命令&#xff0c;用于创建一个名为 "django_env" 的虚拟环境。虚拟环境是一种用于隔离不同Python项目所需依赖的工具。通过创建虚拟环境&#x…

word 如何编写4x4矩阵

百度上给的教程&#xff0c;打印出来没有对齐 https://jingyan.baidu.com/article/6b182309995f8dba58e159fc.html 百度上的方式试了一下&#xff0c;不会对齐。导致公式看起来很奇怪。 下面方式会自动对齐 摸索了一下发现可以用下面这种方式编写 4x4 矩阵。先创建一个 3x3…

SpringSecurity源码学习二:异常处理

目录 1. 原理2. 组件3. ExceptionTranslationFilter3.1 默认过滤器顺序3.2 ExceptionTranslationFilter源码3.2.1 AuthenticationException异常3.2.2 AccessDeniedException异常 总结 1. 原理 Spring Security 异常处理的原理是通过一系列的异常处理器来处理在安全验证和授权过…

基于Linux上MySQL8.*版本的安装-参考官网

本地hadoop环境安装好,并安装好mysql mysql下载地址及选择包 MySQL :: Download MyS的QL Community Server (Archived Versions) mysql安装步骤 下载与上传解压给权限 #mysql安装包上传到/opt下 cd /usr/local/ #解压到此目录 tar -xvf /opt/mysql-8.0.33-linux-glibc2.12-…

[Machine Learning][Part 5]监督学习——逻辑回归

之前文章中提到监督学习的应用可分为两类&#xff1a;线性回归和逻辑回归。和线性回归不同&#xff0c;逻辑回归输出只有0和1。对于一个逻辑回归任务&#xff0c;可以先使用线性回归来预测y。然而我们希望逻辑回归预测模型输出的是0和1&#xff0c;为了达到这个目的&#xff0c…

Ubuntu:VS Code IDE安装ESP-IDF【保姆级】

物联网开发学习笔记——目录索引 参考&#xff1a; VS Code官网&#xff1a;Visual Studio Code - Code Editing. Redefined 乐鑫官网&#xff1a;ESP-IDF 编程指南 - ESP32 VSCode ESP-ID Extension Install 一、前提条件 Visual Studio Code IDE安装ESP-IDF扩展&…

微信小程序 uniapp+vue线上洗衣店业务管理系统演89iu2

本课题意在设计一种系统的、基于用户体验的线上洗衣服务模式&#xff0c;具有如下的研究意义: (1)为用户提供更简单、便捷的洗衣服务模式; (2)为智能柜的盈利模式提供了新的方向; (3)通过线上系统、智能柜与洗衣工厂结合的方式&#xff0c;为洗衣企业构建了一套节 省人力成本的…

使用VS Code终端窗口创建Python虚拟环境

在日常的Python开发中&#xff0c;管理项目的依赖关系是至关重要的。一个非常有用的工具是Python虚拟环境&#xff0c;它允许我们可以在同一计算机上隔离不同项目的依赖&#xff0c;以确保它们不会相互干扰。在本文中&#xff0c;我们将介绍如何在VS Code终端窗口中使用命令mkv…

Java新特性Stream流详解

一、概述 Stream流是Java 8 API添加的一个新的抽象&#xff0c;以一种声明性方式处理数据集合&#xff08;侧重对于源数据计算能力的封装&#xff0c;并且支持序列与并行两种操作方式&#xff09;。 Stream流是对集合&#xff08;Collection&#xff09;对象功能的增强&#xf…

论文阅读:CenterFormer: Center-based Transformer for 3D Object Detection

目录 概要 Motivation 整体架构流程 技术细节 Multi-scale Center Proposal Network Multi-scale Center Transformer Decoder Multi-frame CenterFormer 小结 论文地址&#xff1a;[2209.05588] CenterFormer: Center-based Transformer for 3D Object Detection (arx…

WSL Ubuntu 22.04.2 LTS 安装paddle踩坑日记

使用conda安装paddlepaddle-gpu: conda install paddlepaddle-gpu2.5.1 cudatoolkit11.7 -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/Paddle/ -c conda-forge 等待安装... 报错处理&#xff1a; (1)(1)PreconditionNotMetError: Cannot load cudnn shared libr…

原子性操作

原子性操作是指一个操作在执行过程中不会被中断&#xff0c;要么全部执行成功&#xff0c;要么全部不执行&#xff0c;不会出现部分执行的情况。原子性操作对于多线程并发编程至关重要&#xff0c;因为它可以确保多个线程之间不会出现竞态条件或数据不一致性。 在计算机科学中…

205、使用消息队列实现 RPC(远程过程调用)模型的 服务器端 和 客户端

目录 ★ RPC模型&#xff08;远程过程调用通信模型&#xff09;▲ 完整过程&#xff1a;代码演示总体流程解释&#xff1a;ConstantUtil 常量工具类ConnectionUtil RabbitMQ连接工具类Server 服务端Client 客户端测试结果服务端客户端 完整代码ConstantUtil 常量工具类Connecti…