依赖包的优先级设置

问题出现:
一个老项目的退款功能被微信支付后台停用,原因是xml解析工具有漏洞风险,
    微信客服给出的解决方案是使用官方的补丁。
使用补丁后发现:xml-api包与jdk自带的包冲突。
具体原因:
    xml-api包的某个类与jdk自带的某个类具有相同的全限定名,但是xml-api包中并没有相关实现,
    IDE没有依赖jdk自带的包,而是优先依赖xml-api包,导致项目无法完成编译。
尝试解决:
在 Maven 中排除 xml-api 包:
    从父 pom 里面做排除:
        但是项目年代久远,各种类库的依赖盘根错节,
        到父 pom 里面没找到依赖,到依赖的自定义基本库里面也没找到。
        况且考虑到父 pom 被其他项目依赖的可能性,所以还是想想其他办法。
    全局排除:
        在 pom 文件里加入冲突包的依赖,然后再排除包里全部的内容:
            <dependency>
                <groupId></groupId>
                <artifactId></artifactId>
                <version></version>
                <exclusions>
                    <exclusion>
                        <groupId>*</groupId>
                        <artifactId>*</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        这个方法能够排除掉项目对 xml-api 包里的全部依赖;
            但是因为先导入后排除,项目依然会优先依赖 xml-api 包;所以问题还是没有解决。
推荐方案:
修改依赖包的优先级:

    因为这个老项目是用 Eclipse 开发,先说 Eclipse 操作方法。
    Eclipse:
        设置 build path order;
        把优先级高的包放到上面,
        所以可以把 jre 的包放到最上面。
    
    顺便看了下 IDEA 的设置,也能修改优先级。
    IDEA:
        修改 classpath order:
        菜单:File -> Project Structure -> Modules
        快捷键:Ctrl + Alt + Shift + S  -> Modules
        把优先级高的包放到上面,
        IDEA 中,jdk 自带的包默认就是最高优先级,所以使用 IDEA 不会出现类似的问题。
    

传送门:http://blog.51cto.com/1350814...
本文系笔者原创
转载请注明出处
—————————————

### Java JAR包加载优先级设置方法 在Java应用程序中,尤其是复杂的模块化应用或插件系统中,确保某些JAR包中的类能够被优先加载是非常重要的。这不仅影响程序的行为一致性,还可能决定系统的稳定性性能。 #### 类加载器的作用范围与层次结构 Java虚拟机通过一系列的类加载器来管理不同来源的字节码文件(即`.class`文件)。这些类加载器按照一定的顺序工作,在默认情况下遵循父委托模型——当请求加载某个类时,子类加载器会先让其父类加载器尝试加载该类;只有当父类加载器无法找到对应的类定义时,才会由当前类加载器继续查找并加载[^1]。 对于想要改变这种行为的应用开发者来说,可以通过自定义类加载器的方式实现更灵活的控制策略。例如: - **创建新的ClassLoader实例**:继承`URLClassLoader`或其他合适的基类,并重写必要的方法; - **调整启动参数**:利用`-Xbootclasspath/p:`选项指定额外的引导类路径,使得特定库可以在标准API之前得到处理; - **修改MANIFEST.MF清单文件**:向JAR包内部添加扩展属性如`Class-Path`字段,指示其他依赖项的位置关系。 需要注意的是,上述操作可能会破坏原有环境的安全性假设以及兼容性保障措施,因此应当谨慎评估风险后再做决策。 #### Maven构建工具的影响因素 除了直接操纵运行期配置之外,项目打包阶段的选择同样会对最终制品内的资源布局造成显著差异。特别是在采用Maven作为自动化构建手段的情况下,POM.xml文件里的依赖声明决定了哪些第三方组件会被纳入成品之中及其版本号等细节信息。如果多个地方引入了相同名称却来自不同出处或是具有不匹配修订级别的构件,则极有可能引发所谓的“JAR Hell”。 为了避免此类情况的发生,建议采取以下预防性维护动作之一或多者组合运用: - 明确指明所需的具体坐标集,减少间接引用带来的不确定性; - 使用排除标签(`<exclusions>`)剔除不必要的传递依赖; - 借助于Shade Plugin之类的辅助功能将所有外部链接转换成本地副本形式嵌入单一可执行单元之内。 以上做法有助于维持清晰可控的技术栈边界,从而简化后续部署运维流程的同时也降低了潜在冲突发生的概率[^2]。 ```xml <!-- Example of excluding transitive dependencies --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>test</scope> <exclusions> <exclusion> <groupId>*</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency> ``` #### 外部配置覆盖机制 有时为了适应不同的运行环境需求,或者是在测试期间快速切换设定值而不必重新编译整个工程,人们倾向于把部分敏感数据移至独立文件保存起来并通过适当途径注入到正在工作的进程中去。Spring Boot框架在这方面提供了便捷的支持,允许用户借助命令行参数、环境变量甚至是专门设计好的接口完成这项任务。 具体而言,更新已封装成JAR格式分发版中的application.properties内容可以参照如下步骤实施: 1. 准备好待替换的目标文档; 2. 执行带有更新指令的shell脚本,比如: ```bash jar uf your-app-name.jar BOOT-INF/classes/application.properties ``` 这样做之后即可保证新加入的信息能够在下次调用`java -jar ...`的时候生效[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值