我是靠谱客的博主 机灵蜡烛,最近开发中收集的这篇文章主要介绍自定义ClassLoader 解决不同版本jar共存,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1.有这样一个变态需求,有两个不同版本的dubbo.jar包,我们需要在项目中动态指定要运行哪个版本,改如何做?

不同版本jar包准备

package classloader;

public class Dubbo {
	public void invoke() {
		System.err.println("我是Dubbo的V1版本");
	}
}

将上面代码export成dubbo-v1.jar
接下来准备另一个版本的,注意类的全路径一定是相同的。

package classloader;

public class Dubbo {
	public void invoke() {
		System.err.println("我是Dubbo的V2版本");
	}
}

将上面代码export成dubbo-v2.jar

客户端将两个jar引入,然后运行

public class Client {

	public static void main(String[] args) {
		Dubbo dubbo = new Dubbo();
		dubbo.invoke();
	}
}

程序运行:
我是Dubbo的V1版本

下面我们用一个比较烂的方法来进行解决,修改我们的客户端

public class Client {

	public static void main(String[] args) throws Exception {
		invokeJar("C:/Users/皮吉/Desktop/dobbo-v1.jar");
		invokeJar("C:/Users/皮吉/Desktop/dobbo-v2.jar");

	}

	static class MyClassLoader extends ClassLoader {
		private String jarPath;

		public MyClassLoader(String jarPath) {
			this.jarPath = jarPath;
		}

		@Override
		public Class<?> loadClass(String className) throws ClassNotFoundException {
			byte[] b;
			try {
				// 只对我们的Dubbo类进行 class构造
				if (className.startsWith("classloader.Dubbo")) {
					b = findJar(className);
					return defineClass(className, b, 0, b.length);
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			return super.loadClass(className);
		}

		// 从jar中找到指定class转换成字节流
		private byte[] findJar(String className) throws IOException {
			String tmp = className.replaceAll("\.", "/");
			@SuppressWarnings("resource")
			JarFile jar = new JarFile(jarPath);
			JarEntry entry = jar.getJarEntry(tmp + ".class");
			InputStream is = jar.getInputStream(entry);
			ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
			int nextValue = is.read();
			while (-1 != nextValue) {
				byteStream.write(nextValue);
				nextValue = is.read();
			}
			return byteStream.toByteArray();
		}

	}

	private static void invokeJar(String jar) throws Exception {
		MyClassLoader v = new MyClassLoader(jar);
		Class<?> clazz = v.loadClass("classloader.Dubbo");
		Object object = clazz.newInstance();
		Method method = clazz.getMethod("invoke", null);
		method.invoke(object, null);
	}
}

执行结果
在这里插入图片描述
这样我们根据jar路径,并且用自定义的classloader加载变成class,然后反射调用class,这是可行的。

强烈推荐一套Java进阶博客,都是干货,走向架构师不是梦!

Java进阶全套博客

最后

以上就是机灵蜡烛为你收集整理的自定义ClassLoader 解决不同版本jar共存的全部内容,希望文章能够帮你解决自定义ClassLoader 解决不同版本jar共存所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部