美文网首页
Java自定义类加载器解决jar文件冲突

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

作者: 侯亮平dm | 来源:发表于2021-11-01 09:38 被阅读0次

大多数情况下,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<String,byte[]> clazz;
    public UnconventionalClassLoader(String ...files) throws IOException {
        clazz=new HashMap<>();
        for (String file : files) {
            JarFile jarFile = new JarFile(file);
            Enumeration<JarEntry> 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文件冲突

    大多数情况下,jar 文件的冲突 maven,gradle 等依赖管理都能自动处理。但是,一些情况下,这些工具也显...

  • Java-类加载器

    每个java程序至少有3个类加载器: 引导类加载器: 负责加载系统类,通常从rt.jar文件中进行加载。通常由C语...

  • 创建一个java.lang.Test类,能被加载吗?

    java中类加载器有三种: Bootstrap类加载器 负责加载java的核心类包,比如rt.jar 拓展类加载...

  • 热修复类加载项目实战

    android 与 java 的类加载器 类别加载文件类加载器分类java.class 文件{{java类加载机制...

  • java类加载

    1.类加载器1.BootStrapClassLoader 启动类加载器。加载rt.jar 以及 java. 开头...

  • class(三)ClassLoader类加载机制

    字节码文件是如何被加载的?以及加载时机 java中的已有的类加载器 双亲委派机制 通过自定义类加载器加载磁盘的字节...

  • 一个java文件的一生

    .java文件——javac——class文件——进入类加载子系统——选择类加载器(引导类加载器、扩展类加载器、应...

  • 类加载器

    类加载器类加载器负责装入类,搜索网络、jar、zip、文件夹、二进制数据、内存等指定位置的类资源。一个java程序...

  • java类加载机制、类加载器、自定义类加载器

    java类加载机制、类加载器、自定义类加载器 类加载机制 java类从被加载到JVM到卸载出JVM,整个生命周期包...

  • 类加载阅读目录

    什么是类加载器 类加载器与类的”相同“判断 类加载器种类 双亲委派模型 类加载过程 自定义类加载器 JAVA热部署...

网友评论

      本文标题:Java自定义类加载器解决jar文件冲突

      本文链接:https://www.haomeiwen.com/subject/dhepwltx.html