Java 开发中的指定外部 Jar 路径详解
哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛
今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。
我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。
小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!
前言
在上期文章中,我们讨论了 Java 项目中依赖管理的基础,详细介绍了如何使用Maven和Gradle等工具来引入和管理第三方库。在现代软件开发中,依赖库的管理变得尤为重要,它不仅提升了开发效率,还可以减少代码重复与潜在的错误。
然而,在某些场景下,我们需要直接引用本地或远程的 JAR 文件,而不依赖像 Maven 这样的构建工具。这种情况在处理外部库、第三方 SDK、或是自定义的工具类库时尤为常见。如何在 Java 中指定外部 JAR 路径,便成为了开发者的常见需求。本文将详细解析这一操作,并结合具体的使用案例和场景分析其优缺点。
摘要
本文将围绕如何在 Java 中指定外部 JAR 路径展开,介绍不同的方式来加载外部 JAR,并展示其在开发和运行中的具体应用场景。文章内容包括 Java 源码解析、使用案例、应用场景分析、常用类与方法介绍、优缺点分析及测试用例。通过本文,您将掌握如何有效地在 Java 项目中加载和使用外部 JAR 文件。
概述
在 Java 开发中,JAR(Java Archive)文件是用来打包多个 Java 类、元数据和资源文件的压缩包。通常,开发者会通过工具如 Maven 来自动下载并管理这些依赖库。然而,某些情况下,开发者需要手动指定和加载外部 JAR 文件,特别是在不使用构建工具时或者遇到特殊的第三方依赖库。
指定外部 JAR 路径的常用场景包括:
- 使用本地的自定义库或 SDK。
- 引用不在中央仓库(如 Maven Central)中的 JAR 文件。
- 需要跨项目复用相同的 JAR 库。
接下来我们将讨论如何在 Java 中通过不同方式指定这些外部 JAR 路径。
源码解析
在 Java 中,指定外部 JAR 路径的方式有多种,主要包括以下几种方法:
1. 通过命令行 -classpath
或 -cp
参数
这是最简单、最常见的一种方式,尤其在小型项目或临时项目中。
java -cp /path/to/external/jar/your-external-library.jar com.example.MainClass
在这个命令中,-cp
指定了 JAR 文件的路径,com.example.MainClass
是主类。通过这种方式,Java 将在运行时找到并加载指定的 JAR 文件。
2. 在 IDE 中指定 JAR 路径(以 Eclipse 为例)
在使用 Eclipse、IntelliJ IDEA 等 IDE 时,通常可以通过项目的构建路径(Build Path)来添加外部 JAR。
步骤:
- 右键点击项目 -> Build Path -> Configure Build Path。
- 在 “Libraries” 选项卡中点击 “Add External JARs”。
- 选择需要添加的 JAR 文件,点击 “Apply and Close”。
通过这种方式,IDE 会自动将该 JAR 文件添加到项目的类路径中,无需额外在命令行中指定。
3. 通过 MANIFEST 文件配置 JAR 路径
当打包自己的 JAR 文件时,可以在 MANIFEST.MF
文件中指定所需的外部 JAR 文件路径。这对于打包为可执行 JAR(Executable JAR)的项目尤为有用。
Manifest-Version: 1.0
Main-Class: com.example.MainClass
Class-Path: lib/your-external-library.jar
在该例子中,Class-Path
选项指定了外部 JAR 的相对路径。
4. 通过编程方式动态加载 JAR 文件
在某些高级场景下,可能需要动态加载 JAR 文件。例如,运行时才确定所需的 JAR 文件或模块。在这种情况下,可以使用 Java 的 URLClassLoader
类来实现。
import java.net.URL;
import java.net.URLClassLoader;
import java.lang.reflect.Method;public class DynamicJarLoader {public static void main(String[] args) throws Exception {URL[] jarUrls = {new URL("file:///path/to/your-external-library.jar")};URLClassLoader classLoader = new URLClassLoader(jarUrls);Class<?> loadedClass = classLoader.loadClass("com.example.SomeClass");Method method = loadedClass.getMethod("someMethod");method.invoke(loadedClass.newInstance());}
}
这种方法通常用于插件系统或模块化应用中,允许动态加载和卸载特定的模块。
代码解析:
如下是具体的代码解析,希望对大家有所帮助:
这段Java代码定义了一个名为 DynamicJarLoader
的类,其中包含 main
方法。该方法演示了如何动态地从外部JAR文件加载类、获取该类的方法并调用它。
下面是这段代码的中文解释:
-
import java.net.URL;
:导入了Java网络编程中的URL
类。 -
import java.net.URLClassLoader;
:导入了Java网络编程中的URLClassLoader
类。 -
import java.lang.reflect.Method;
:导入了Java反射编程中的Method
类。 -
public class DynamicJarLoader { ... }
:定义了一个名为DynamicJarLoader
的公共类。 -
public static void main(String[] args) throws Exception { ... }
:定义了程序的主入口点main
方法,并声明可能抛出的异常。 -
URL[] jarUrls = {new URL("file:///path/to/your-external-library.jar")};
:创建了一个包含单个URL的数组,该URL指向外部JAR文件的路径。 -
URLClassLoader classLoader = new URLClassLoader(jarUrls);
:使用URL数组创建了一个URLClassLoader
实例,用于从指定的JAR文件加载类。 -
Class<?> loadedClass = classLoader.loadClass("com.example.SomeClass");
:调用URLClassLoader
的loadClass
方法,加载名为 “com.example.SomeClass” 的类。 -
Method method = loadedClass.getMethod("someMethod");
:使用Java反射API获取loadedClass
的名为 “someMethod” 的public
方法。 -
method.invoke(loadedClass.newInstance());
:调用上一步获取的方法。invoke
方法的第一个参数是要在其实例上调用方法的对象,这里使用loadedClass.newInstance()
创建了 “com.example.SomeClass” 类的实例。
注意:代码中使用了 newInstance
方法,它在Java 9中已被弃用。如果你使用的是Java 9或更高版本,应该修改代码如下:
Object instance = loadedClass.getDeclaredConstructor().newInstance();
Method method = loadedClass.getMethod("someMethod");
method.invoke(instance);
总言之,我这个示例演示了如何动态加载JAR文件中的类、获取类的公共方法并调用它。这在需要在运行时加载和执行未知或不固定的代码时非常有用。通过反射API,可以在不知道具体类结构的情况下操作类和对象。
使用案例分享
案例1:跨项目共享自定义工具库
某开发团队有一套自定义的工具库,并且团队内的所有项目都需要使用它。由于该库不是公开发布的,所以没有放到 Maven 中。他们选择了手动将该工具库打包为 JAR 文件,并在各个项目中手动添加此 JAR 文件到类路径中。
通过上述几种方式,团队可以轻松在项目中引用这个自定义库,并保证所有项目都能使用相同的版本。
案例2:本地测试第三方 SDK
在开发过程中,有时需要使用第三方 SDK,而该 SDK 并未上传到公共仓库。开发者可以手动下载 JAR 文件,并在 IDE 或命令行中指定该 JAR 路径,以便快速测试和验证 SDK 的功能。
应用场景分析
适用场景:
- 快速集成第三方库,不需要复杂的依赖管理。
- 使用本地开发的 JAR 文件进行测试。
- 在不使用构建工具的项目中手动管理依赖。
不适用场景:
- 项目需要频繁更新和管理大量依赖时,手动管理 JAR 文件显然效率低下且容易出错。
- 当需要在多个环境中持续集成、持续交付时,使用构建工具(如 Maven 或 Gradle)自动管理依赖更加方便。
优缺点分析
优点
- 简单直接,适合小型项目或临时任务。
- 无需依赖额外的构建工具即可加载外部库。
- 灵活性高,可在运行时动态加载 JAR 文件。
缺点
- 手动管理 JAR 文件会增加复杂度,特别是在依赖关系较多的项目中。
- 不支持自动更新和依赖冲突解决,容易出现版本兼容性问题。
- 无法享受 Maven/Gradle 等工具带来的依赖管理和构建自动化优势。
核心类方法介绍
URLClassLoader
URLClassLoader
是 Java 提供的用于动态加载 JAR 文件的类。通过 URLClassLoader,开发者可以在程序运行时动态加载外部库。
URL[] jarUrls = {new URL("file:///path/to/your-external-library.jar")};
URLClassLoader classLoader = new URLClassLoader(jarUrls);
Class.forName
Class.forName
方法用于加载类,结合 URLClassLoader
,可以加载指定路径的类。
Class<?> loadedClass = classLoader.loadClass("com.example.SomeClass");
测试用例
import org.junit.Test;
import java.net.URL;
import java.net.URLClassLoader;public class JarLoadingTest {@Testpublic void testLoadExternalJar() throws Exception {URL[] jarUrls = {new URL("file:///path/to/your-external-library.jar")};URLClassLoader classLoader = new URLClassLoader(jarUrls);Class<?> loadedClass = classLoader.loadClass("com.example.SomeClass");Object instance = loadedClass.newInstance();assertNotNull(instance);}
}
通过此测试用例,可以验证外部 JAR 文件是否成功加载并实例化类。
代码解析:
如下是具体的代码解析,希望对大家有所帮助:
这段Java代码定义了一个名为 JarLoadingTest
的类,其中包含一个用于测试从外部JAR文件加载类的单元测试方法 testLoadExternalJar
。
下面是这段代码的中文解释:
-
import org.junit.Test;
:导入了JUnit测试框架中的Test
注解。 -
import java.net.URL;
:导入了Java网络编程中的URL
类,用于表示统一资源定位符。 -
import java.net.URLClassLoader;
:导入了Java网络编程中的URLClassLoader
类,它允许从指定的URL加载类和资源。 -
public class JarLoadingTest { ... }
:定义了一个名为JarLoadingTest
的公共类。 -
@Test
:这是一个JUnit注解,表示接下来的方法是测试方法。 -
public void testLoadExternalJar() throws Exception { ... }
:定义了一个名为testLoadExternalJar
的测试方法,它声明了可能抛出的异常。 -
URL[] jarUrls = {new URL("file:///path/to/your-external-library.jar")};
:创建了一个包含单个URL的数组,该URL指向外部JAR文件的路径。 -
URLClassLoader classLoader = new URLClassLoader(jarUrls);
:使用URL数组创建了一个URLClassLoader
实例,用于从指定的JAR文件加载类。 -
Class<?> loadedClass = classLoader.loadClass("com.example.SomeClass");
:调用URLClassLoader
的loadClass
方法,加载名为 “com.example.SomeClass” 的类。 -
Object instance = loadedClass.newInstance();
:调用Class
的newInstance
方法创建 “com.example.SomeClass” 类的实例。 -
assertNotNull(instance);
:使用JUnit的断言方法assertNotNull
来验证加载的类实例不为null
。
注意:代码中有一个错误。Class
类的 newInstance
方法已经在Java 9中被弃用,并在Java 9及以后的版本中被 getDeclaredConstructor().newInstance()
方法取代。所以,如果你使用的是Java 9或更高版本,应该修改代码如下:
Object instance = loadedClass.getDeclaredConstructor().newInstance();
总言之,我这个测试用例的目的是验证从外部JAR文件加载类并创建其实例的功能。通过创建一个 URLClassLoader
并使用它来加载指定的类,然后创建该类的实例并断言该实例不为空,来确保加载过程成功。
小结
Java 中指定外部 JAR 文件路径的几种方式为我们提供了灵活的解决方案,无论是命令行方式、IDE 集成,还是动态加载 JAR,都有其应用场景与优势。在日常开发中,选择合适的方式来引用外部依赖,将有效提升开发效率与项目管理能力。
总结
在本文中,我们详细解析了 如何在 Java 中指定外部 JAR 路径,并探讨了不同方法的适用场景、优缺点以及实践案例。虽然手动管理外部 JAR 文件相比使用构建工具略显繁琐,但在某些特殊场景下仍具有重要的应用价值。通过本文的学习,开发者可以更好地应对不同场景下的依赖加载需求,灵活地在项目中使用外部 JAR 文件。
… …
文末
好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。
… …
学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!
wished for you successed !!!
⭐️若喜欢我,就请关注我叭。
⭐️若对您有用,就请点赞叭。
⭐️若有疑问,就请评论留言告诉我叭。
相关文章:
Java 开发中的指定外部 Jar 路径详解
哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互…...

python爬虫--小白篇【selenium自动爬取文件】
一、问题描述 在学习或工作中需要爬取文件资源时,由于文件数量太多,手动单个下载文件效率低,操作麻烦,采用selenium框架自动爬取文件数据是不二选择。如需要爬取下面网站中包含的全部pdf文件,并将其转为Markdown格式。…...

TI毫米波雷达原始数据解析之Lane数据交换
TI毫米波雷达原始数据解析之Lane数据交换 背景Lane 定义Lane 确认确认LVDS Lane 数量的Matlab 代码数据格式参考 背景 解析使用mmWave Studio 抓取的ADC Data Lane 定义 芯片与DCA100之间的数据使用LVDS接口传输,使用mmWave Studio 配置过程中有一个选项是LVDS L…...

overscroll-behavior-解决H5在ios上过度滚动的默认行为
1. 问题 开发H5的过程中,经常会有android和ios两边系统需要兼容的情况。在ios上一直有个问题是当H5内容触及到页面顶部或底部时,还是可以被人为的往下或往下拉动界面。当然可能有的情况是比较适用的,比如你往下拉动,然后在导航栏…...

Nacos配置中心总结
Nacos配置中心总结 Nacos配置文件的加载顺序和优先级 加载顺序 nacos作为配置中心时,需要在bootstrap.yml文件中添加nacos config相关的配置,这样系统启动时就能先去拉取nacos server上的配置了。拉取过来后会和本地配置文件进行合并。 bootstrap.ym…...

rouyi(前后端分离版本)配置
从gitee上下载,复制下载地址,到 点击Clone,下载完成, 先运行后端,在运行前端 运行后端: 1.配置数据库,在Navicat软件中,连接->mysql->名字自己起(rouyi-vue-blog),用户名roo…...

超大规模分类(一):噪声对比估计(Noise Contrastive Estimation, NCE)
NCE损失对应的论文为《A fast and simple algorithm for training neural probabilistic language models》,发表于2012年的ICML会议。 背景 在2012年,语言模型一般采用n-gram的方法,统计单词/上下文间的共现关系,比神经概率语言…...

Windows 下安装 triton 教程
目录 背景解决方法方法一:(治标不治本)方法二:(triton-windows)- 安装 MSVC 和 Windows SDK- vcredist 安装- whl 安装- 验证 背景 triton 目前官方只有Linux 版本,若未安装,则会出…...

复盘与导出工具最新版9.15重磅发布-全新UI兼容所有windows系统
在9.11版本的基础上大更新: 1.应付费用户需求修复当更换明亮风格时软件超过电脑屏幕的bug!!!!! 2.支持所有windows版本,32/64位的win xp/7/8/10/11 3.修复开盘啦涨停原因排序bug 4.全新ui风格 5提前爆料:.9.2版本的分开…...

家用电器销售系统|Java|SSM|JSP|
【技术栈】 1⃣️:架构: B/S、MVC 2⃣️:系统环境:Windowsh/Mac 3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7 4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、JSP、jquery,html 5⃣️数据库可…...

NRF24L01模块通信实验
NRF24L01简要介绍 这里主要介绍模块的最重要的参数,废话就不多介绍了。 该模块是一款无线通信模块,一个模块即可同时具备发射和接收数据的功能,但是要想实现通信必须使用两个模块之间才能进行通信。NRF24L01模块使用的总线控制方式为SPI总…...
2024年12月CCF-GESP编程能力等级认证Scratch图形化编程三级真题解析
本文收录于《Scratch等级认证CCF-GESP图形化真题解析》专栏,专栏总目录:点这里,订阅后可阅读专栏内所有文章。 一、单选题(一共 15 个题目,每题 2 分,共 30 分) 第 1 题 2024 年 10 月 8 日,诺贝尔物理学奖“意外地”颁给了两位计算机科学家约翰霍普菲尔德(John J. …...

【MySQL系列】VARCHAR为啥一般是255
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

图文教程:使用PowerDesigner导出数据库表结构为Word/Html文档
1、第一种情况-无数据库表,但有数据模型 1.1 使用PowerDesigner已完成数据建模 您已经使用PowerDesigner完成数据库建模,如下图: 1.2 Report配置和导出 1、点击:Report->Reports,如下图: 2、点击&…...
Coroutine 基础五 —— Flow 之 Channel 篇
1、Channel 与 Flow 简介与对比 所有知识都可总结为一个字 —— 流。包括数据流、事件流、状态流。 开发中最常用的 StateFlow 提供状态订阅。可以将一些信息包进 StateFlow 中进行保存。比如界面上显示的字符串,或者系统级别的信息,如用户状态。装进 …...

快速掌握Elasticsearch检索之二:滚动查询(scrool)获取全量数据(golang)
Elasticsearch8.17.0在mac上的安装 Kibana8.17.0在mac上的安装 Elasticsearch检索方案之一:使用fromsize实现分页 1、滚动查询的使用场景 滚动查询区别于上一篇文章介绍的使用from、size分页检索,最大的特点是,它能够检索超过10000条外的…...
C++设计模式:状态模式(自动售货机)
什么是状态模式? 状态模式是一种行为型设计模式,它允许一个对象在其内部状态发生改变时,动态改变其行为。通过将状态相关的逻辑封装到独立的类中,状态模式能够将状态管理与行为解耦,从而让系统更加灵活和可维护。 通…...

【网络安全实验室】脚本关实战详情
难道向上攀爬的那条路,不是比站在顶峰更让人热血澎湃吗 1.key又又找不到了 点击链接,burp抓包,发送到重放模块,点击go 得到key 2.快速口算 python3脚本 得到key 3.这个题目是空的 试了一圈最后发现是 4.怎么就是不弹出key呢…...

ts总结一下
ts基础应用 /*** 泛型工具类型*/ interface IProps {id: string;title: string;children: number[]; } type omita Omit<IProps, id | title>; const omitaA: omita {children: [1] }; type picka Pick<IProps, id | title>; const pickaA: picka {id: ,title…...

MySQL数据库笔记——主从复制
大家好,这里是Good Note,关注 公主号:Goodnote,本文详细介绍 MySQL的主从复制,从原理到配置再到同步过程。 文章目录 简介核心组件主从复制的原理作用主从复制的线程模型主从复制的模式形式复制的方式设计复制机制主从…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...

基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...

打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用
一、方案背景 在现代生产与生活场景中,如工厂高危作业区、医院手术室、公共场景等,人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式,存在效率低、覆盖面不足、判断主观性强等问题,难以满足对人员打手机行为精…...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
目录 节点的功能承载层(GATT/Adv)局限性: 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能,如 Configuration …...
从零手写Java版本的LSM Tree (一):LSM Tree 概述
🔥 推荐一个高质量的Java LSM Tree开源项目! https://github.com/brianxiadong/java-lsm-tree java-lsm-tree 是一个从零实现的Log-Structured Merge Tree,专为高并发写入场景设计。 核心亮点: ⚡ 极致性能:写入速度超…...
湖北理元理律师事务所:债务清偿方案中的法律技术革新
文/金融法律研究组 当前债务服务市场存在结构性矛盾:债权人追求快速回款,债务人需要喘息空间。湖北理元理律师事务所通过创新法律技术,在《企业破产法》《民法典》框架下构建梯度清偿模型,实现多方利益平衡。 一、个人债务优化的…...

20250607在荣品的PRO-RK3566开发板的Android13系统下实现长按开机之后出现插入适配器不会自动启动的问题的解决
20250607在荣品的PRO-RK3566开发板的Android13系统下实现长按开机之后出现插入适配器不会自动启动的问题的解决 2025/6/7 17:20 缘起: 1、根据RK809的DATASHEET,短按开机【100ms/500ms】/长按关机,长按关机。6s/8s/10s 我在网上找到的DATASHE…...