自定义类加载器国密版本冲突
对接三方接口经常使用到国密加密包(bcprov),此时系统已经引入了1.5版本,而三方提供的sdk中引用了1.6版版本,两个版本有冲突,如果系统加载到1.5版本的将会加密异常(各种奇怪的异常),本文的解决方案是指定一个类加载器,完成指定加载sdk和1.6版本的加密包
自定义类类加载器
package com.huakai.springenv.config.test;
import java.net.URL;
import java.net.URLClassLoader;
public class IsolatedClassLoader extends URLClassLoader {
private final ClassLoader parent;
public IsolatedClassLoader(URL[] urls, ClassLoader parent) {
super(urls, parent);
this.parent = parent;
}
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
synchronized (getClassLoadingLock(name)) {
Class<?> c = findLoadedClass(name);
if (c == null) {
try{
c = this.findClass(name);
}catch (Exception e){
}
if (c == null) {
try {
c = this.parent.loadClass(name);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
}
使用sdk
private OpenBankHttpClient getOpenBankHttpClient() throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException, IOException {
// 指定版本的加密包
URL urlbc = AbcMarketingConfig.class.getClassLoader().getResource("./abc/bcprov-jdk15on-1.68");
// 三方sdk
URL urlSM2SdkImpl = AbcMarketingConfig.class.getClassLoader().getResource("./abc/openbank-sdk-java-sm");
URL[] urls= new URL[] {urlbc,urlSM2SdkImpl};
IsolatedClassLoader sdkClassLoader = new IsolatedClassLoader(urls, AbcMarketingConfig.class.getClassLoader());
// 使用自定义类加载器加载三方SDK的主类
Class<?> requestParamsClass = sdkClassLoader.loadClass("com.abchina.openbank.OpenBankHttpClient");
// 获取私有构造函数
Constructor<?> constructor = requestParamsClass.getDeclaredConstructor();
// 设置构造函数可访问
constructor.setAccessible(true);
// 使用构造函数创建对象
return (OpenBankHttpClient) constructor.newInstance();
}