java -cp运行之jar包加载顺序问题(非常重要)

简介: 有没有经常在项目部署时发生java.lang.NoSuchMethodError、java.lang.ClassNotFoundException与java.

有没有经常在项目部署时发生java.lang.NoSuchMethodError、java.lang.ClassNotFoundException与java.lang.NoClassDefFoundError的错误(告诉你,一般都是jar包冲突了),那么怎样排查呢?排查到jar冲突后又怎样解决呢?

(非常重要的特:java -cp 是有顺序的!!!)

1. jar冲突故障排查:

以springboot工程为例,只需在使用@SpringBootApplication的入口类上加上:

Class<?> c = Class.forName("org.aa.bb.XXClass");

System.out.println(c.getProtectionDomain().getCodeSource().getLocation())

然后启动,查看打印的jar路径,即就是当前实际加载的那个包下的类。

2. jar加载顺序举例说:

a.jar, b.jar 都有 MyTest这个类。

java -cp a.jar:b.jar

那么 这个MyTest 拿到的到底 是哪个jar包的?

答案是:cp 前面的那个(经验所知,springboot扫描加载yml、properties文件也是同理,排在前面的classpath被加载,后面的将不会被加载)。

怎么解决呢?

若是使用shell脚本添加的classpath,可参考:关于shell sort使用

在关键shell代码中需要排序`CLASSPATH`字符串:

# classpath addition for release.

for file in `ls -a "$base_dir"/libs/* | sort -r`;

do

    CLASSPATH="$CLASSPATH":"$file"

done


Oracle官网关于cp顺序说明

Specification Order

The order in which you specify multiple class path entries is

important. The Java interpreter will look for classes in the

directories in the order they appear in the class path variable. In

the previous example, the Java interpreter will first look for a

needed class in the directory /java/MyClasses. Only when it does not

find a class with the proper name in that directory will the

interpreter look in the /java/OtherClasses directory.

目录
相关文章
|
2月前
|
安全 Java API
JAVA并发编程JUC包之CAS原理
在JDK 1.5之后,Java API引入了`java.util.concurrent`包(简称JUC包),提供了多种并发工具类,如原子类`AtomicXX`、线程池`Executors`、信号量`Semaphore`、阻塞队列等。这些工具类简化了并发编程的复杂度。原子类`Atomic`尤其重要,它提供了线程安全的变量更新方法,支持整型、长整型、布尔型、数组及对象属性的原子修改。结合`volatile`关键字,可以实现多线程环境下共享变量的安全修改。
|
3月前
|
Java 应用服务中间件 Spring
为什么SpringBoot的 jar 可以直接运行?
SpringBoot的 jar 可以直接运行的原因
359 2
|
11天前
|
数据采集 分布式计算 Java
Kettle的Java开发环境需要什么jar包?
【10月更文挑战第24天】Kettle的Java开发环境需要什么jar包?
55 2
|
1月前
|
存储 数据可视化 Java
震惊!如何在linux下部署项目,部署/运行jar包 超详细保姆级教程!
如何在Linux系统下部署和运行Java项目jar包,包括传输文件到Linux、使用nohup命令运行jar包、查看端口状态、杀死进程和查看项目运行状态,以及如何解决“没有主清单属性”的错误。
327 1
震惊!如何在linux下部署项目,部署/运行jar包 超详细保姆级教程!
|
24天前
|
Java Apache Maven
Java/Spring项目的包开头为什么是com?
本文介绍了 Maven 项目的初始结构,并详细解释了 Java 包命名惯例中的域名反转规则。通过域名反转(如 `com.example`),可以确保包名的唯一性,避免命名冲突,提高代码的可读性和逻辑分层。文章还讨论了域名反转的好处,包括避免命名冲突、全球唯一性、提高代码可读性和逻辑分层。最后,作者提出了一个关于包名的问题,引发读者思考。
Java/Spring项目的包开头为什么是com?
|
1月前
|
Java Windows
如何在windows上运行jar包/JAR文件 如何在cmd上运行 jar包 保姆级教程 超详细
本文提供了一个详细的教程,解释了如何在Windows操作系统的命令提示符(cmd)中运行JAR文件。
692 1
|
2月前
|
Java API 数据处理
Java 包(package)的作用详解
在 Java 中,包(package)用于组织和管理类与接口,具有多项关键作用:1)系统化组织代码,便于理解和维护;2)提供命名空间,避免类名冲突;3)支持访问控制,如 public、protected、默认和 private,增强封装性;4)提升代码可维护性,实现模块化开发;5)简化导入机制,使代码更简洁;6)促进模块化编程,提高代码重用率;7)管理第三方库,避免命名冲突;8)支持 API 设计,便于功能调用;9)配合自动化构建工具,优化项目管理;10)促进团队协作,明确模块归属。合理运用包能显著提升代码质量和开发效率。
|
2月前
|
Java 数据安全/隐私保护
Java 包(package)的使用详解
Java中的包(`package`)用于组织类和接口,避免类名冲突并控制访问权限,提升代码的可维护性和可重用性。通过`package`关键字定义包,创建相应目录结构即可实现。包可通过`import`语句导入,支持导入具体类或整个包。Java提供多种访问权限修饰符(`public`、`protected`、`default`、`private`),以及丰富的标准库包(如`java.lang`、`java.util`等)。合理的包命名和使用对大型项目的开发至关重要。
|
3月前
|
Java Maven 数据库
|
3月前
|
Java
Java应用结构规范问题之在biz层的convert包实现转换的问题如何解决
Java应用结构规范问题之在biz层的convert包实现转换的问题如何解决