Java 加载外部 Jar 中的类并通过反射调用类中的方法
目录
问题
类加载器
获取外部 jar 包中的类以及方法
调用外部 jar 包中的方法
问题
工作中遇到一个需求,客户端将第三方的 jar 包上传到服务器中,系统需要解析出上传的 jar 中所有类以及类下的方法(方法名,方法输入参数类型,方法返回值类型),并将这些类以及方法提供给配置人员选择,由配置人员自由配置需要用到的方法。
类加载器
Java 虚拟机在加载类文件时,默认情况下使用自带的三个类加载器
- BootstrapClassLoader:加载 %JRE_HOME%\jre\lib 下的 jar 和 class
- ExtentionClassLoader:加载 %JRE_HOME%\jre\lib\ext 下的 jar 和 class
- AppClassLoader:加载当前应用路径下的 class
在 JDK 1.8 的 rt.jar 中,Launcher 类里定义了这三个类加载器
可以从源码中看到,三个加载器分别指定了不同的加载路径来加载类
BootstrapClassLoader
private static String bootClassPath = System.getProperty("sun.boot.class.path");
ExtentionClassLoader
System.getProperty("java.class.path")
AppClassLoader
System.getProperty("java.ext.dirs")
三个加载器通过双亲委派机制来加载类文件,每个加载器都只负责加载自己负责的加载路径,显然,如果要自定义加载路径,从而实现加载外部 jar 包,就必须自定义加载器来实现。
在 JDK 1.8 中,可以看到 AppClassLoader 和 ExtClassLoader 都是继承 URLClassLoader 来实现的。若要加载外部的 jar 包,只需拿到外部 jar 包的 URL 路径,用 URLClassLoader 便可以加载。
获取外部 jar 包中的类以及方法
public class JarUtils {/*** 这些默认方法不打印*/private static List<String> DEFAULT_METHODS = Arrays.asList("wait", "equals", "notify", "notifyAll", "toString", "hashCode" , "getClass");public static void parseJar(File file) throws Exception {URL url = file.toURI().toURL();try (URLClassLoader myClassLoader = new URLClassLoader(new URL[]{url}, Thread.currentThread().getContextClassLoader())) {//通过jarFile和JarEntry得到所有的类JarFile jar = new JarFile(file);//返回zip文件条目的枚举Enumeration<JarEntry> enumFiles = jar.entries();JarEntry entry;//测试此枚举是否包含更多的元素while (enumFiles.hasMoreElements()) {entry = enumFiles.nextElement();if (entry.getName().indexOf("META-INF") < 0) {String classFullName = entry.getName();if (classFullName.endsWith(".class")) {//去掉后缀.classString className = classFullName.substring(0, classFullName.length() - 6).replace("/", "."); //类名Class<?> myclass = myClassLoader.loadClass(className);System.out.println(String.format("类名:%s", className));//得到类中包含的属性Method[] methods = myclass.getMethods();for (Method method : methods) {String methodName = method.getName();if (DEFAULT_METHODS.contains(methodName)) {continue;}//方法名System.out.print(String.format("方法名:%s; ", methodName));Class<?>[] parameterTypes = method.getParameterTypes(); //方法参数类型System.out.print(String.format("方法参数类型:%s; ", Arrays.stream(parameterTypes).map(Class::getSimpleName).collect(joining(","))));System.out.println(String.format("方法返回类型:%s; ", method.getReturnType().getSimpleName())); //方法返回值类型}System.out.println("***************************");}}}} catch (IOException e) {throw e;}}}
调用外部 jar 包中的方法
public class JarUtils {public static void executeMethod(File f, String className, String methodName, Class[] classes, Object[] objects) {//通过URLClassLoader加载外部jartry (URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{f.toURI().toURL()})) {//获取外部jar里面的具体类对象Class<?> targetClass = urlClassLoader.loadClass(className);//创建对象实例Object instance = targetClass.newInstance();//获取实例当中的方法名为show,参数只有一个且类型为string的public方法Method method = targetClass.getMethod(methodName, classes);//传入实例以及方法参数信息执行这个方法Object returnObj = method.invoke(instance, objects);System.out.println(returnObj);} catch (Exception e) {e.printStackTrace();}}
}
相关文章:
Java 加载外部 Jar 中的类并通过反射调用类中的方法
目录 问题 类加载器 获取外部 jar 包中的类以及方法 调用外部 jar 包中的方法 问题 工作中遇到一个需求,客户端将第三方的 jar 包上传到服务器中,系统需要解析出上传的 jar 中所有类以及类下的方法(方法名,方法输入参数类型&…...

Arduino+ESP8266+华为云物联网平台实现智能开关
前言 最近在做一个物联网项目,涉及到智能开关的开发。目前已经实现简单的TCP通信远程控制,但是考虑到后期的设备管理以及设备通信所需要的技术和服务器的维护成本,我决定将设备接入云平台。本文将详细阐述如何利用华为云的物联网平台&#x…...

使用 python 拆分 excel 文件
文章目录 1、安装虚拟环境(在特定文件夹内)2、脚本 split.sh3、运行脚本(在特定文件夹内)4、结果 1、安装虚拟环境(在特定文件夹内) brew install python3 xcode-select --install python3 -m venv my_pan…...
uniapp小程序中onShareAppMessage(OBJECT)实现带参数的分享功能
一、引言 小程序中用户点击分享后,在 js 中定义 onShareAppMessage 处理函数(和 onLoad 等生命周期函数同级),设置该页面的分享信息。 用户点击分享按钮的时候会调用。这个分享按钮可能是小程序右上角原生菜单自带的分享按钮&…...

5个免费的3D钣金CAD软件
如果你正在设计简单的折叠钣金零件,则只需设计一些具有圆角半径的法兰:一个简单的钣金模块。 首先,你可以采用老式方式绘图并以 2D 方式完成所有操作。 许多传统制造商仍在使用 2D DWG 和 DXF 图纸。 因此,你很有可能只需快速起草…...

3.26学习总结
java 实例变量和局部变量 实例变量是记录这个类中对象的特点的每一个对象的实例变量都可以不同(例如名字,性别等),其中一个对象的实例变量改变不会影响其他的变量. 类变量是一种特殊的实例变量,他的特殊在于所有的对象的类变量都是相同的,当一个对象改变了类变量那么所有对象…...
Cisco Catalyst3850交换机RTU license使用方法
1 情况说明 客户处采购了4台3850-14T交换机,在配置的时候发现OSPF不支持, 查询原因为当前license不支持 (lanbase, 只能支持2层功能) 报错如下: Access-3850-1(config)#router ospf 100 Protocol not in this image2 如何处理&a…...
简明 Python 教程(第5章 函数)
本章介绍了函数的基本概念和使用方法,包括定义函数、传递参数、局部变量、全局变量、默认参数、关键字参数、返回值和文档字符串。 掌握这些概念对于编写结构化和可维护的Python代码至关重要。 定义函数 使用def关键字 定义函数始于def关键字,它告诉P…...
flutter 保存一堆多语言翻译词条,由key和value组成
原理: 1.从String列表里面获取某个value: List<String> jsonStrings [{"name": "John", "age": 30},{"name": "Jane", "age": 25},{"name": "Bob", "age…...
3月25日,每日信息差
🎖 素材来源官方媒体/网络新闻 🎄 京东汽车将和小米汽车进行深度合作 🌍 百度将为苹果国行iPhone16提供AI功能?百度方面称暂无回应 🌋 国产结核病新型mRNA疫苗即将问世 🎁 美国发布严重地磁暴预警ÿ…...

Git常用指令使用
摘要:之前代码管理都是借助于fork、sourceTree等图形工具,最近发现直接用命令也好用,就总结Git常用的指令 1、Git的介绍 1.1 git官网 安装: Git - Downloading Packagehttps://git-scm.com/download/mac Mac上安装,直接使…...

数据结构与算法 顺序表的基本运算
一、实验内容 编写一个程序实现,实现顺序表的各种基本运算(假设顺序表的元素类型为char),并以此为基础设计一个程序完成下列功能: (1)初始化顺序表; (2)采…...
docker部署nacos(单机与集群)
拉去nacos镜像 [rootlocalhost keepalived]# docker search nacos NAME DESCRIPTION STARS OFFICIAL nacos/nacos-server This project contains a Docker image meant t… 464 …...

开启Safari手势支持
在使用Safari 的时候,大家有没有觉得不支持手势使用起来不是很方便, 触摸板只支持少量简单的手势,如缩放,滚动等。如果使用鼠标的用户,则完全无法使用手势。经过折腾研究,使用CirMenu应用可以完美解决这个要…...

Amuse:.NET application for stable diffusion
目录 Welcome to Amuse! Features Why Choose Amuse? Key Highlights Paint To Image Text To Image Image To Image Image Inpaint Model Manager Hardware Requirements Compute Requirements Memory Requirements System Requirements Realtime Requirements…...
Java冒泡排序详细讲解
冒泡排序是一种简单但效率较低的排序算法,它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。具体实现如下: 算法步骤: 比较相邻的元素:从第一个元素开始,依次…...
python数据解析xpath
前言一、安装?二、使用步骤1.基本使用**【2】谓语(Predicates)**案例 前言 xpath在Python的爬虫学习中,起着举足轻重的地位,对比正则表达式 re两者可以完成同样的工作,实现的功能也差不多,但xp…...

工业镜头常用参数之实效F(Fno.)和像圈
Fno. 工业镜头中常用到的参数F,有时候用F/#,Fno.来表示,指的是镜头通光能力的参数。它可用镜头焦距及入瞳直径来表示,也可通过镜头数值孔径(NA)和光学放大倍率(β)来计算。有效Fno.…...

what is apache?
Apache 通常指 Apache Software Foundation (ASF) 或 Apache HTTP Server,两者都是计算机软件领域的重要实体。 Apache 软件基金会 (ASF):Apache 软件基金会是一个开发开源软件项目的非营利组织。它为涵盖软件开发各个方面的广泛项目提供支持,…...

【二叉树】Leetcode 94. 二叉树的中序遍历【简单】
二叉树的中序遍历 给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。 示例 1: 输入:root [1,null,2,3] 输出:[1,3,2] 解题思路 中序遍历是一种二叉树遍历方式,按照“左根右”的顺序遍历二叉树节点。 1、递归…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...

Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...

力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...