两个jar包冲突但两个都要使用的解决方案

方案一 使用URLClassLoader加载jar包这样就与冲突jar包隔离开了。

使用方法繁琐需要反射来调用方法。
适用于使用某个jar包少量方法的应用。

实现

import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;

public abstract class TestUtils {
	private static URLClassLoader clsLoader;
	private static Class haxClass;
	private static Class SM3DigestClass;

    static {
        //类加载器加载bcprov-jdk15on-1.60.jar
        try {
       		 //加载bcprov-jdk15on-1.60.jar包,放在了src下
			clsLoader = URLClassLoader.newInstance(new URL[] {new URL(TestUtils .class.getResource("/")+"bcprov-jdk15on-1.60.jar")});
			//加载需要使用的类(包名称加上类名)
			SM3DigestClass = clsLoader.loadClass("org.bouncycastle.crypto.digests.SM3Digest");
        	haxClass = clsLoader.loadClass("org.bouncycastle.util.encoders.Hex");
        	log.info("bcprov-jdk15on-1.60.jar被加载了!");
		} catch (Exception e) {
			log.error("bcprov-jdk15on-1.60.jar加载失败!,原因:"+e.getMessage());
		}
    }
    
    
    /**
     * 生成SM3编码
     * 由于bcprov-jdk15on-1.60.jar与bcprov-jdk16-139.jar冲突所以改用类加载器加载jar包并以反射调用方法
     * @param source
     * @return
     */
	  public static String sM3encode(String source) {
	        try {
		    	byte[] md = new byte[32];
		    	byte[] msg = source.getBytes("UTF-8");
		    	//实例化对象
		        Object sM3DigestObject=SM3DigestClass.newInstance();
		        Object haxObject = haxClass.newInstance();
		        //调用需要调用的方法(通过反射)
				Method update =SM3DigestClass.getMethod("update", byte[].class,int.class,int.class);
				update.invoke(sM3DigestObject, msg, 0, msg.length);
				Method doFinal =SM3DigestClass.getMethod("doFinal", byte[].class,int.class);
				doFinal.invoke(sM3DigestObject, md, 0);
				Method encode =haxClass.getMethod("encode", byte[].class);
				byte[] haxEncodeString =(byte[])encode.invoke(haxObject, md);
		    	String s = new String(haxEncodeString);
		    	return s;
	        } catch (Exception e) {
	        	log.error("sM3encode编码错误!原因:"+e.getMessage());
	            return null;
	        }
	    }  
    
}

方案二 可以去找到jar包的源码修改包名然后放在自己的工程里或在打个jar包引入项目

方案三 如果找不到jar包源码那就反编译

  1. 通过jd-gui等工具反编译(反编译的有部分存在错误的反编译,需要根据逻辑自行更正)
  2. 使用IDEA新建工程(注意改为自己的包名
  3. 将反编译后的源码放入工程中
  4. 运行测试重新打包
  5. 引入项目

小伙伴们,如果有更好方案请留言告诉我,谢谢!

  • 7
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当你尝试在一个项目中使用两个或更多的相同包名和类名的JARJava ARchive,即jar文件)时,如果它们包含同一类或方法,可能会发生冲突。这种冲突通常发生在你试图替换或扩展某个库的功能时。原始jar文件中的类会覆盖或优先于重写jar文件中的类,这可能导致意想不到的行为,尤其是在类加载机制中。 以下是一些可能遇到的问题: 1. 类加载顺序问题:如果原始jar在类路径(Classpath)中位于重写jar之前,那么原始类将被加载,即使重写jar中提供了不同实现。 2. 方法覆盖:如果两个jar都有同名的方法,且签名(参数列表和返回类型)相同,调用时可能会执行的是原始版本,除非明确指定了特定版本。 3. 依赖问题:如果重写jar依赖于原始jar的其他部分,而这些部分未被正确替换,可能会导致运行时错误。 为了解决这类冲突,你可以考虑以下几种策略: 1. **修改类加载顺序**:通过调整类路径或使用`javaagent`来改变类加载顺序,确保重写jar先于原始jar被加载。 2. **使用模块系统(Java 9+)**:利用模块化,可以将相关的类和依赖分开,避免直接冲突。 3. **命名空间**:为重写的部分添加不同的包名或前缀,使其与原始版本区分开。 4. **替换依赖**:在构建时替换掉原始jar,确保只使用你想要的重写版本。 5. **使用代理或适配器类**:如果可能,创建适配器类将原始API包装在自己的实现中,避免直接修改核心库。 如果你有具体的冲突实例,我可以提供更详细的解决方案或分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值