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的主从复制,从原理到配置再到同步过程。 文章目录 简介核心组件主从复制的原理作用主从复制的线程模型主从复制的模式形式复制的方式设计复制机制主从…...

OpenAI发布o3:圣诞前夜的AI惊喜,颠覆性突破还是技术焦虑?
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...

欧拉-伯努利梁自由波动的频散关系
梁和杆都是一维结构,但是梁的弯曲波比杆的纵波要复杂多。例如即使最简单的欧拉-伯努利(Euler-Bernoulli)梁的弯曲波也具有频散特征,且当梁的特征尺寸和弯曲波波长满足某个比值时,欧拉-伯努利梁不再适用,需要引入铁摩辛克(Timoshenko)梁模型。 考察某一欧拉-伯努利梁,长度…...

Cursor小试1.生成一个网页的接口请求工具
一般开发过程中,会涉及到接口的调试,往往有时候开发的电脑不是我们自己的,没有安装一些类似postman 的接口调用工具,所以发现问题或者要测试某些接口是否正常的时候会很麻烦,而且现在网上也没有找到很好的免费的网页端接口请求的网址,所以我们使用Cursor来编写这样一个小工具, …...

Xilinx DCI技术
Xilinx DCI技术 DCI技术概述Xilinx DCI技术实际使用某些Bank特殊DCI要求 DCI级联技术DCI端接方式阻抗控制驱动器(源端接)半阻抗控制阻抗驱动器(源端接)分体式DCI(戴维宁等效端接到VCCO/2)DCI和三态DCI&…...

Kubernetes Pod 优雅关闭:如何让容器平稳“退休”?
Kubernetes Pod 优雅关闭:如何让容器平稳“退休”? 在 Kubernetes 中,Pod 是应用的基本单元。你可能会遇到需要停止某个 Pod 或容器的情况,可能是因为要更新、调整或故障恢复。在这种情况下,Pod 的优雅关闭࿰…...

鸿蒙应用开发(1)
可能以为通过 鸿蒙应用开发启航计划(点我去看上一节) 的内容,就足够了,其实还没有。 可是我还是要告诉你,你还需要学习新的语言 -- ArkTS。 ,ArkTS是HUAWEI开发的程序语言。你需要学习这门语言。这会花费你…...

SimForge HSF 案例分享|复杂仿真应用定制——UAVSim无人机仿真APP(技术篇)
导读 「神工坊」核心技术——「SimForge HSF高性能数值模拟引擎」支持工程计算应用的快速开发、自动并行,以及多域耦合、AI求解加速,目前已实现航发整机数值模拟等多个系统级高保真数值模拟应用落地,支持10亿阶、100w核心量级的高效求解。其低…...

使用 Adaptive Mesh Refinement 加速 CFD 仿真:最佳实践
CFD 仿真中的网格划分挑战 技术的进步正在增强设计探索,数值仿真在优化工程设计方面发挥着至关重要的作用。通常,计算流体动力学 (CFD) 仿真从定制的手工网格开始,具有精细和粗糙的区域,以平衡分辨率和单元…...

前端-动画库Lottie 3分钟学会使用
目录 1. Lottie地址 2. 使用html实操 3. 也可以选择其他的语言 1. Lottie地址 LottieFiles: Download Free lightweight animations for website & apps.Effortlessly bring the smallest, free, ready-to-use motion graphics for the web, app, social, and designs.…...

智能工厂的设计软件 应用场景的一个例子:为AI聊天工具添加一个知识系统 之5
本文要点 前端 问题描述语言 本文继续完善 “描述” ---现在我们应该可以将它称为 “问题problem描述语言 ”。 它 通过对话框的question 引发 表征的issue 的“涌现” 最终 厘清应用程序的“problem”。即它合并了 ISO七层模型中的上面三层,通过将三层 分别形成…...