Java自定义类加载器解决jar文件冲突

大多数情况下,jar 文件的冲突 maven,gradle 等依赖管理都能自动处理。但是,一些情况下,这些工具也显得无能为力。
假设foo.jar 1.0与2.0 不能完全兼容,项目需要使用一个第三方的sdk依赖 foo.jar 1.0 ,但是项目原有的代码又依赖foo.jar 2.0, 这时候,如果使用1.0 或者2.0 都是不行的。

我们知道,Java中的类的唯一标志是 类加载器+ 类的全限定名,那么我们只需要把foo.jar 1.0 让自定义的类加载器去加载,这样foo.jar 1.0中的

package demo;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class UnconventionalClassLoader extends ClassLoader {
    private Map clazz;
    public UnconventionalClassLoader(String ...files) throws IOException {
        clazz=new HashMap<>();
        for (String file : files) {
            JarFile jarFile = new JarFile(file);
            Enumeration entries = jarFile.entries();
            while (entries.hasMoreElements()){
                JarEntry jarEntry = entries.nextElement();
                if(jarEntry.getName().endsWith(".class")){
                    try (InputStream inputStream = jarFile.getInputStream(jarEntry)) {
                        int pos=0;
                        int len;
                        byte[] buff=new byte[inputStream.available()];
                        while ((len=inputStream.read(buff,pos,buff.length-pos))>0){
                            pos+=len;
                        }
                        String className=jarEntry.getName().replace("/",".")
                                .replace(".class","");
                        clazz.put(className,buff);
                    }
                }
            }
        }
    }


    @Override
    protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
        synchronized (getClassLoadingLock(name)) {
            Class cz = findLoadedClass(name);
            if(cz==null){
                byte[] bytes = clazz.get(name);
                if(bytes==null){
                    cz=super.loadClass(name,resolve);
                }else{
                    cz=defineClass(name,bytes,0,bytes.length);
                }
            }
            return cz;
        }
    }

 //使用方式展示
    public static void main(String[] args) throws ClassNotFoundException, IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {


        UnconventionalClassLoader unconventionalClassLoader = new UnconventionalClassLoader("E:\\commons-codec-1.10.jar");

        Class aClass = unconventionalClassLoader.loadClass("org.apache.commons.codec.binary.StringUtils");
        System.out.println(aClass.getClassLoader().getClass().getName());

        Method equals = aClass.getMethod("equals",CharSequence.class,CharSequence.class);

        boolean b= (boolean) equals.invoke(null,"s1","s2");

        System.out.println(b);




    }
}

你可能感兴趣的:(Java自定义类加载器解决jar文件冲突)