`

永远不要在Classpath里边放有版本冲突的jar包

阅读更多

总结:

BUG: 部署时报错,Spring Bean加载顺序有问题,或部分class找不到。

曾遇到:部署时,服务器上未将部分jar包删除,在一台服务器上始终无法部署成功,而另一台始终可以成功部署。

很多人都说这个问题太明显,这你还要说。虽然很明显,但是人们还是不断的犯错误。尤其是有时候侥幸心里给了人们可称之机。

只说一个web应用的例子吧。我们一般会在WEB-INF/lib目录中放自己需要的jar包。远古时代,当程序员自己手工管理这些jar包的时候,也不太会什么问题。可是有了Maven之后,程序员只是在pom.xml中申明自己需要的jar包,Maven会代劳地将这些jar包最终打在WEB-INF/lib中。再加上Maven的依赖传递、版本仲裁等牛X的机制,可以说很多程序员最后自己也不知道WEB-INF/lib下面到底打了哪些jar包的哪个版本。

如果碰巧,通过乱七八糟的依赖,你的classpath中有多个不同版本的spring的jar包。有人说:“什么?那不可能。”别急,我指得是这种情况。

 

WEB-INF/lib/spring-2.0.1.jar
WEB-INF/lib/spring-beans-2.5.4.jar
WEB-INF/lib/spring-core-2.5.4.jar

由于Maven的版本仲裁机制,我们是不可能同时有两个spring-*.*.*.jar。但是我们可以有一个spring完整的jar和两个spring modules jar包,而且他们不是同一版本的。如果版本仲裁控制的不好,这非常有可能。

然后……天下大乱了……

也许你会说,只要JVM保证每次加载的,要么一直是老版本的jar包或者地一直是新版本的jar,那就没事儿了。因为,另一个版本的jar包因了排在了classpath后边,是永远加载不到的。如果有这样的想法,那你就错了。没几天你就会崩溃的发现,JVM是一会加载老版本,一会加载新版本,有时候还混合着加载,再抛出一大堆ClassNotFoundException跟你玩。为什么会这样?

拿JBoss举例吧,JBoss说:“我是用java.io.File.listFiles()来列出来WEB-INF/lib目录下的jar包,然后严格地按顺序从前往后,一个jar包一个jar包的查找类的。”

嗯,看起来JBoss还挺严禁的。再看看Java怎么说,java.io.File.listFiles()的Javadoc说:“……There is no guarantee that the name strings in the resulting array will appear in any specific order; they are not, in particular, guaranteed to appear in alphabetical order.……”

啊?什么意思?它说它不保证返回结果的顺序?尤其是 不保证 是按文件名字典序排。也就是说好一点的情况,你在同一台机器,同一个版本的JVM上运行,没准儿每次返回的文件列表顺序还能相同。但是一旦部署到线上的机器,或者换了另一个开发环境,完全有可能listFiles()返回的文件列表顺序是不一样的。所以我们完全不能做任何关于顺序的假设。

所以,也就是说如果你的WEB-INF/lib/下面放了多个不同版本的jar包,你是完全无法控制JVM或者说JBoss去先加载哪个jar包中的类的。还是老老实实的想办法,把版本通过Maven仲裁掉。如果两部分代码确实要依赖两个不同版本的Spring,那恭喜你,发代码吧。

 

 

 

分享到:
评论

相关推荐

    所有要用到的jar包

    在Java开发过程中,`jar`(Java ...总之,`jar`包在Java开发中扮演着至关重要的角色,它们是代码的载体,同时也是项目间共享功能和实现依赖管理的基础。正确理解和使用`jar`包,能够提升开发效率,确保项目稳定运行。

    如何在WebSphere中解决jar包冲突.doc

    OSGi 框架允许不同的应用程序共享同一个 jar 包,并且提供了一种机制来解决版本冲突问题。 结论 解决 jar 包冲突问题是大型 Java 软件开发中的一個重要问题。本文讨论了 WebSphere 中类加载器的层次结构,并提供了...

    泛微E-cology 二次开发Java Jar包

    1. **导入jar包**:将所需的jar包添加到项目的类路径(ClassPath)中,这样编译器和运行时环境就能找到并加载这些库。在IDE如Eclipse或IntelliJ IDEA中,可以直接通过项目设置导入外部库。 2. **理解API**:每个jar...

    关于执行java命令引入外部jar包方法

    例如,假设我们有一个名为`Test`的主类,它依赖于`mysqlJdbc.jar`和`a.jar`两个JAR包,那么可以在命令行中这样执行: ```bash java -cp e:\mysqlJdbc.jar;e:\a.jar Test ``` 这里,`-cp`参数后面跟的是所有JAR包的...

    东方通开发需要的jar包

    在使用这些jar包时,开发者需要将它们添加到项目的类路径(classpath)中,以便编译和运行时能够找到所需的类。对于Maven或Gradle等构建工具的用户,可以通过在pom.xml或build.gradle文件中指定依赖来自动管理这些...

    java的jar包

    总的来说,Java的JAR包在软件开发中扮演着关键角色,它们封装了功能丰富的库和框架,帮助开发者高效地构建复杂的应用。理解如何正确使用和管理这些JAR包,对于提升开发效率和保证项目质量具有重要意义。在开发过程中...

    连接mysql数据库的jar包(多个版本)

    - **添加依赖**:在Java项目中,通常将`mysql-connector-java`的jar包添加到项目的类路径(classpath)中,这可以通过IDE(如Eclipse、IntelliJ IDEA)的设置完成,或者在构建脚本(如Maven的pom.xml或Gradle的...

    java语言开发jar包_jar包_java_

    3. **版本控制**:不同的JAR包可以代表不同版本的库,这有助于管理项目依赖和版本冲突。例如,`jboss-logging-3.3.0.Final.jar`是JBoss的日志框架的一个特定版本,确保项目使用一致的API和功能。 4. **安全**:JAR...

    lib中的jar lib中的jar包

    - **构建工具**:Maven、Gradle等现代构建工具能自动管理`jar`依赖,下载并将其放入指定的`lib`目录,同时解决依赖冲突。 - **版本控制**:不同的项目可能依赖不同版本的`jar`包,使用版本控制工具(如Git)可确保...

    java动态添加外部jar包到classpath的实例详解

    Java 动态添加外部jar包到classpath是指在Java应用程序中动态地加载外部jar包到classpath中,以便在不重新启动服务器的情况下使用最新的代码。这项技术在项目开发过程中非常有用,因为它可以让开发者在不影响应用...

    velocity所需的jar包

    为了正确地在项目中使用这些jar包,你需要将它们添加到你的类路径(classpath)中。如果是传统的Java项目,通常将它们放入`lib`目录下,并在构建脚本(如`build.xml`或`pom.xml`)中配置依赖。如果是使用现代的构建...

    数据库驱动jar包

    在Java项目中,引入这些数据库驱动jar包通常有以下步骤: 1. 将jar包下载到本地文件系统。 2. 添加到项目的类路径(classpath),这可以通过IDE(如Eclipse、IntelliJ IDEA)的配置设置完成,或者在构建脚本(如...

    达梦数据库JAR包

    达梦数据库JAR包是专门为Java开发者设计的,用于在Java应用程序中与达梦数据库进行交互的工具包。达梦数据库是中国自主研发的一款高性能、高可用性的关系型数据库管理系统,广泛应用于政府、金融、电信等关键领域,...

    java开发jar包

    在版本控制中,JAR包应遵循语义版本(SemVer)原则,确保兼容性。 9. **Spring Boot与JAR** Spring Boot项目通常生成自包含的可执行JAR,内部包含了Tomcat服务器和其他依赖,可以直接运行。这种方式使得部署更简单...

    jar包解析工具

    `jar`包解析工具对于开发者来说至关重要,尤其是在处理依赖管理和调试过程中。本篇文章将深入探讨`jar`包解析工具及其在项目开发中的应用。 首先,我们要理解`jar`包的基本结构。一个`jar`文件由一系列的`class`...

    mysql57驱动jar包

    在Java编程环境中,为了与MySQL数据库进行交互,我们需要使用JDBC(Java Database Connectivity)驱动,这就是MySQL 5.7驱动jar包的作用。这个jar包包含了所有必要的类和接口,使得Java应用程序能够通过标准的JDBC ...

    mysql连接驱动jar包

    如果是IDE(如Eclipse或IntelliJ IDEA),可以直接将jar包放入项目的lib目录,并在IDE设置中将其包含进类路径。如果是命令行编译,需要确保编译和运行时包含该jar包的位置。 3. 配置数据库连接信息:在Java代码中,...

    jar包所在文件夹

    在构建项目时,如使用Maven或Gradle,这些jar包会被添加到项目的类路径(classpath)中,从而确保程序运行时能够正确地找到并使用它们。 总结来说,`json-lib jar包`用于处理JSON数据,`mysql驱动jar包`是与MySQL...

    spring boot 第三方jar包抽离方案

    【Spring Boot 第三方...然而,需要注意的是,抽离第三方jar包也可能增加运维复杂度,如需管理和更新公共库,以及处理可能的版本冲突问题。因此,在实际操作中,应根据项目的具体需求权衡利弊,选择最适合的优化策略。

    mysql8的驱动jar包

    2. **命令行运行**:如果你在命令行下运行Java程序,可以使用`-cp`或`-classpath`参数指定jar包的位置。 3. **MANIFEST.MF**:如果使用的是Java的可执行jar文件,可以在`META-INF/MANIFEST.MF`文件中添加`Class-Path...

Global site tag (gtag.js) - Google Analytics