项目里已经引入了bcprov-jdk15on-1.54.jar
,并且在很多地方使用.
现在合作方给过来一套新的接入资料,里面有以下jar包.
bcprov-jdk15on-1.69.jar
fintech-java-sdk-core-3.1.0.jar
fintech-java-sdk-kdft-3.1.0.jar
项目中的bcprov-jdk15on存在两个版本,旧的是1.54
,新的是1.69
.
类似于下面这张图:
由于很多地方用到了1.54
版本,所以不能直接升级到1.69
.
现在想实现以下两点:
即本次的升级不会影响到历史功能.
如果不考虑冲突的情况,正常使用新jar,示例代码如下:
DefaultKdClient defaultKdClient = KdSdkConfig.getDefaultClient();
DemoApiInfo demoApiInfo = new DemoApiInfo();
Map<String, String> params = new HashMap<>();
DefaultKdRequest<Object> kdRequest = new DefaultKdRequest<>(demoApiInfo,
params);
我想过使用类加载器,可能是理解的还不到位,我觉得每个类都这样引入比较麻烦,比如DefaultKdClient
// custom class loader: CustomClassLoader
CustomClassLoader classLoader = new CustomClassLoader();
Class<?> defaultKdClient = classLoader.loadClass("xx.DefaultKdClient");
而且我不太确定这样能确保fintech-java-sdk-core-3.1.0.jar、fintech-java-sdk-kdft-3.1.0.jar中依赖的bcprov-jdk15on能是1.69版本.
除此之外,我也想过新建一个项目,这样就可以有不同的运行时,使得bcprov-jdk15on不再冲突,但是新项目需要新的维护成本,这种方式感觉也不太好.
上面的场景,请问有什么比较好的解决方案,谢谢~
可以新建一个最简单的maven项目,通过maven-shade-plugin
插件,把老版本groupId重命名后打个包,配置大概如下(注意看注释部分的重命名配置)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>shade-hutool57</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>5.7.22</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>true</createDependencyReducedPom>
<relocations>
<relocation>
<!-- 原始groupId -->
<pattern>cn.hutool</pattern>
<!-- 重命名groupId -->
<shadedPattern>cn.hutool.charles</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
然后拷贝target里的xxx.jar,在正式项目里添加依赖,配置如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>hutool-multi-version</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>5.8.20</version>
</dependency>
<dependency>
<groupId>cn.hutool.v57</groupId>
<artifactId>hutool-core</artifactId>
<version>5.7.22</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/shade-hutool57-1.0-SNAPSHOT.jar</systemPath>
</dependency>
</dependencies>
</project>
使用的时候,import新版本还是老版本需要自己决定,Java import无法别名,一个类不能同时用新老版本
package org.example;
//import cn.hutool.core.util.RandomUtil;
import cn.hutool.charles.core.util.RandomUtil;
public class Main {
public static void main(String[] args) {
System.out.println(RandomUtil.randomString(32));
}
}
使用自定义类加载器能解决你的问题,例子。
这里给的例子只是一种最简单的解决方式,但是它肯定不适合你的情况,因为在你的代码中,调用一个 jar 肯定是直接通过类名调用的,而例子中给的只是反射。
因此需要你再针对 jar 的方法包装一下,比如你可以新建一个类 Bcprov_1_54
,加载 bcprov-jdk15on-1.54.jar
,代理你用到的方法,然后再新建一个类 Bcprov_1_69
,加载 bcprov-jdk15on-1.69.jar
。
这样你就拥有了两个版本的调用方式。
如果上面jar 包都有源码的话,可以对基中一个版本整体通过包名重构,这样就可以解决冲突,需要的测试和维护成本较低。
如果可能的话,还是建议将其低版本升级,否则发现新的漏洞就只能自己维护了。
问题内容: 在我的Java项目中,我需要使用依赖于 lucene-3.6.2的* neo4j-1.9.3 和 依赖于 lucene-4.4.0的 ElasticSearch 。我知道,如果我想直接使用两个版本的Lucene,可以使用ClassLoader从Lucene加载不同的类。 * 但是问题是我现在不会直接使用lucene的api。有什么方法可以在neo4j的api运行时加载lucene-3.
问题内容: 我必须使用两个版本的Java(1.6.21和1.7)。我公司的代码取决于1.6_21,我们计划使用人工制品。我们正在本地测试工件,但是工件需要Java 1.7或更高版本。我希望我的默认Java主目录指向1.6_21,对于工件应为1.7。 但是问题出在我安装Java 7以后,它就将自身设置为默认值。我读过很多文章,它们解释了如何管理Java的两个版本,但是我的工件和Eclipse必须同时
问题内容: 我有一个Java项目正在使用两个导入的具有相同类()的jar 。导入类时,有没有一种方法可以明确说明要使用哪个jar?使用: 似乎按照构建路径顺序的顺序使用该类,但是由于某种原因,似乎并非如此 在运行时。我正在Eclipse中构建项目。 问题答案: 您不能仅在Java源代码中执行所要求的操作。Java不是为此而设计的。 这是一种糟糕的情况,只有使用自定义类加载器才能可靠地处理它们,每个
问题内容: 我知道对于经验丰富的编码人员来说,这可能是一个愚蠢的问题。但是我有一个库(http客户端),我的项目中使用的其他一些框架/jar也需要。但它们都需要不同的主要版本,例如: 类加载器是否足够智能以某种方式将它们分开?很有可能不是吗?万一所有三个jar中的Class都相同,Classloader如何处理这个问题。加载哪一个?为什么? Classloader是仅拾取一个jar还是将其任意混合
问题内容: 我有一个Cordova项目,并且正在为其构建一个android插件。然后,我的插件使用了使用菱形运算(<>)的库。我尝试运行它,但收到此错误: 当我跑步时: 我在发布之前先进行研究,有些人通过将ant更改为 但这对我没有用。 我还尝试制作一个文件来设置和,但是它似乎只是在解析主项目,而不是我在插件上使用的子项目。 问题答案: 好的,对我有用的是添加插件使用的所有子项目(库)作为yout
我有两个maven项目:projA和projB 投射依赖于投射 PropB依赖于泽西2.15 projA依赖于hbase测试UTIL hbase测试UTIL取决于1.8。十、 如果projB在没有任何排除的情况下声明了对projA的依赖,那么projB的测试将失败,因为它们使用了Jersey项目中某个类的错误版本(1.8.x)。 如果詹姆士声明依赖于詹姆士组件,那么上面的问题就消失了。但是,新的问