如何使用 ClassLoader 隔离不同版本的 jar 包?
众所周知,因为classloader的隔离机制,一个jvm进程可以同时加载两个同名的class,但是如何使用这两个class呢。只能通过拿到class的引用,反射调用吗?
问题背景:系统A接入多家渠道,需要用到渠道的SDK,但是各个渠道的SDK都依赖了相同的加解密class,例如 org.apache.Cipher,但是版本都不一样。如何让这些SDK在一个JVM进程中无障碍使用。
场景和stackeroverflow这个问题一样:Java Classloader - how to reference different versions of a jar
回答:
这时候 URLClassLoader 就派上用场了。下面是一个例子
public class ChannelCipherManager implements Closeable { private final Map<String, URLClassLoader> cipherClassLoaders = new HashMap<>();
/**
* 注册渠道自己的 cipher jar 包
*/
public void registerCipherJar(String channel, File cipherJar) throws MalformedURLException {
URLClassLoader cipherClassLoader = new URLClassLoader(new URL[]{cipherJar.toURI().toURL()});
cipherClassLoaders.put(channel, cipherClassLoader);
}
/**
* 根据渠道获得对应的 cipher 对象
*/
@SuppressWarnings("unchecked")
public Cipher getCipher(String channel) throws ClassNotFoundException {
if (!cipherClassLoaders.containsKey(channel)) {
// 或者注册一个默认的,找不到渠道就返回该默认值也行
throw new IllegalArgumentException("Channel '" + channel + "' not registered");
}
Class<Cipher> cipherClass = (Class<Cipher>)
cipherClassLoaders.get(channel).loadClass("org.apache.Cipher");
return createCipherInstance(cipherClass);
}
/**
* 创建 Cipher 实例对象
*/
private Cipher createCipherInstance(Class<Cipher> cipherClass) {
return null; // TODO 这个交给你自己实现
}
/**
* 根据需要释放资源
*/
@Override
public void close() throws IOException {
this.cipherClassLoaders.values().forEach(cl -> {
try {
cl.close();
} catch (IOException e) {
// ignore error
}
});
}
}
使用方法:
public static void main(String[] args) throws Exception { ChannelCipherManager ccm = new ChannelCipherManager();
ccm.registerCipherJar("channel1", new File("lib-ch1/cipher.jar"));
ccm.registerCipherJar("channel2", new File("lib-ch2/cipher.jar"));
ccm.registerCipherJar("channel3", new File("lib-ch3/cipher.jar"));
Cipher cipher = ccm.getCipher("channel2");
// ...
}
回答:
如果你最终加密的结果,和版本无关,这你用哪个都没关系,如果是最终结果有差异,自定义classloader,加载外置jar也是可以的
回答:
这两个类的类加载器不一样,调用对应的类加载器就能获取到类
以上是 如何使用 ClassLoader 隔离不同版本的 jar 包? 的全部内容, 来源链接: utcz.com/p/944649.html