项目中有多个版本的jar包时,实现兼容

当服务调用方使用poi 3.17,而被调用方为poi 4.1.2时,通过自定义ClassLoader并设置当前线程的类加载器,实现了不同版本jar包的兼容。详细介绍了从项目结构到方法调用,以及调用方和被调用方的classLoader配置。
摘要由CSDN通过智能技术生成

1. 服务调用方

调用方是poi 3.17 ,被调用方是poi-4.1.2版本

package com.demo;


import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Demo {
   

    public static void main(String[] args) throws IOException {
   
        ClassLoaderUtil.loadJarPath("F:\\IdeaProject1\\hutool-excel-demo2\\lib");

        System.err.println(Thread.currentThread().getContextClassLoader());
        Class clazz = null;
        try {
   
            clazz = Thread.currentThread().getContextClassLoader().loadClass("main.java.com.auto.create.ExcelUtils2");
            System.err.println(clazz);

            Method method = clazz.getMethod("demo",null);
            System.err.println(Thread.currentThread().getContextClassLoader());
            method.invoke(clazz,null);
            System.err.println(Thread.currentThread().getContextClassLoader());
        } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
   
            e.printStackTrace();
        }

    }
}


2. 自定义classLoader


package main.java.com.auto.create;

import java.io.*;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * description 自定义加载类:打破双全委派机制
 *
 * @author Cyber
 *         <p>
 *         Created By 2022/11/22
 * @version 1.0
 */
public class MyJarClassLoader extends URLClassLoader {
   
 
	private static URL[] tempUrl;
	private URL[] allUrl;

	public MyJarClassLoader(String[] paths) {
   
		this(paths, MyJarClassLoader.class.getClassLoader());
	}

	public void addClass(String className) {
   
		try {
   
			classMap.put(className, Class.forName(className));
		} catch (ClassNotFoundException e) {
   
			e.printStackTrace();
		}
	}

	public MyJarClassLoader(String[] paths, ClassLoader parent) {
   
		super(getURLs(paths), parent);
		// 当前线程防止重复读取文件信息,可使用其他缓存代替
		allUrl = tempUrl;

	}

	public MyJarClassLoader(URL[] urls, ClassLoader parent) {
   
		super(urls, parent);
	}

	/**
	 * description 通过文件目录获取目录下所有的jar全路径信息
	 *
	 * @param paths 文件路径
	 * @return java.net.URL[]
	 * @author Cyber
	 *         <p>
	 *         Created by 2022/11/22
	 */
	private static URL[] getURLs(String[] paths) {
   
		if (null == paths || 0 == paths.length) {
   
			throw new RuntimeException("jar包路径不能为空.");
		}
		List<String> dirs = new ArrayList<String>();
		for (String path : paths) {
   
			dirs.add(path);
			MyJarClassLoader.collectDirs(path, dirs);
		}
		List<URL> urls = new ArrayList<URL>();
		for (String path : dirs) {
   
			urls.addAll(doGetURLs(path));
		}
		URL[] threadLocalurls = urls.toArray(new URL[0]);
		tempUrl = threadLocalurls;
		return threadLocalurls;
	}

	/**
	 * description 递归获取文件目录下的根目录
	 *
	 * @param path      文件路径
	 * @param collector 根目录
	 * @return void
	 * @author Cyber
	 *         <p>
	 *         Created by 2022/11/22
	 */
	private static void collectDirs(String path, List<String> collector) {
   
		if (null == path || "".equalsIgnoreCase(path)) {
   
			return;
		}
		File current = new File(path)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值