前言

工作上遇到需要解析Jar包的情况,需要将Jar包里面的类文件获取出来,然后动态调用。

案例

import java.io.File;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class ConfigureJar {

    public static void main(String[] args) throws Exception {
        String path = "E:\\GitHub\\study\\MyProcedure\\lib\\compiler-1.0.jar";//外部jar包的路径
        Set<Class<?>> classes = new LinkedHashSet<Class<?>>();//所有的Class对象
        Map<Class<?>, Annotation[]> classAnnotationMap = new HashMap<Class<?>, Annotation[]>();//每个Class对象上的注释对象
        Map<Class<?>, Map<Method, Annotation[]>> classMethodAnnoMap = new HashMap<Class<?>, Map<Method,Annotation[]>>();//每个Class对象中每个方法上的注释对象

        JarFile jarFile = new JarFile(new File(path));
        URL url = new URL("file:" + path);
        ClassLoader loader = new URLClassLoader(new URL[]{url});//自己定义的classLoader类,把外部路径也加到load路径里,使系统去该路经load对象
        Enumeration<JarEntry> es = jarFile.entries();
        while (es.hasMoreElements()) {
            JarEntry jarEntry = (JarEntry) es.nextElement();
            String name = jarEntry.getName();
            if(name != null && name.endsWith(".class")){//只解析了.class文件,没有解析里面的jar包
                //默认去系统已经定义的路径查找对象,针对外部jar包不能用
                Class<?> c = loader.loadClass(name.replace("/", ".").substring(0,name.length() - 6));//自己定义的loader路径可以找到
                System.out.println(c);
                classes.add(c);
                Annotation[] classAnnos = c.getDeclaredAnnotations();
                classAnnotationMap.put(c, classAnnos);
                Method[] classMethods = c.getDeclaredMethods();
                Map<Method, Annotation[]> methodAnnoMap = new HashMap<Method, Annotation[]>();
                for(int i = 0;i<classMethods.length;i++){
                    Annotation[] a = classMethods[i].getDeclaredAnnotations();
                    methodAnnoMap.put(classMethods[i], a);
                }
                classMethodAnnoMap.put(c, methodAnnoMap);
            }
        }
        System.out.println(classes.size());
    }
}

运行结果:

java 拆包解包 jar包解析_jar包

总结

记录一下代码实现。

This moment will nap, you will have a dream; But this moment study,you will interpret a dream.