自定义类加载器国密版本冲突
对接三方接口经常使用到国密加密包(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;}@Overrideprotected 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");// 三方sdkURL 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();}