再写一遍已经写烂的jar中找冲突类

最近因为因为web容器升级,而容器自带了很多jar,发现和应用中的jar有冲突(相同的类,不同的版本),导致出现NoSuchMethon异常什么的。需求来了,需要比较两个目录下有那些相同的类。这个需求前人已经写烂了,可上网搜索一时找不到合适的,就再写了一遍,并作下记录,方便后来人和将来的自己再用。

不多说,上代码(一次性代码,1小时搞定,如有编程风格问题,敬请谅解):

package com.mikegu.tools.jardiff;

import java.io.File;
import java.io.IOException;

/**
 * 启动入口类
 * 
 * @author haiquan.guhq
 */
public class JarDiffMain {

    /**
     * 输入要比较的两个目录,目录下包含jar,结果输出到控制台。
     */
    public static void main(String[] args) throws IOException {
        if (args.length != 2) {
            System.out.println("please input two compare dirs");
            System.exit(1);
        }
        String firstInputPath = args[0];
        String secondInputPath = args[1];

        File file = new File(firstInputPath);
        File[] listFiles = file.listFiles();
        for (File oneFile : listFiles) {
            if (oneFile.isFile() && oneFile.getAbsolutePath().endsWith(".jar")) {
                String jarName = oneFile.getName();
                ZipDecompression.decompression(oneFile.getAbsolutePath(), firstInputPath + "/tmp/"
                        + jarName); // 解压
                ClassNameFinder.find(jarName, firstInputPath + "/tmp/" + jarName, 1); // 查找
            }
        }

        file = new File(secondInputPath);
        listFiles = file.listFiles();
        for (File oneFile : listFiles) {
            if (oneFile.isFile() && oneFile.getAbsolutePath().endsWith(".jar")) {
                String jarName = oneFile.getName();
                ZipDecompression.decompression(oneFile.getAbsolutePath(), secondInputPath + "/tmp/"
                        + jarName);
                ClassNameFinder.find(jarName, secondInputPath + "/tmp/" + jarName, 2);
            }
        }

        ClassNameFinder.compare();
    }
}
package com.mikegu.tools.jardiff;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;

/**
 * 搜索和比较相同的类
 */
public class ClassNameFinder {

    private static Map<String, List<ClassInfosDO>> firstMap  = new HashMap<String, List<ClassInfosDO>>();
    private static Map<String, List<ClassInfosDO>> secondMap = new HashMap<String, List<ClassInfosDO>>();

    public static void find(String jarName, String path, int order) {

        List<String> allClassName = new ArrayList<String>();
        //根据路径取得全类
        getAllClassName(path, allClassName, path.length() + 1);

        if (allClassName != null) {
            for (String one : allClassName) {
                ClassInfosDO classInfosDO = new ClassInfosDO(one, jarName);
                List<ClassInfosDO> list = getOrderMap(order).get(one);
                if (list == null) {
                    List<ClassInfosDO> arrayList = new ArrayList<ClassInfosDO>();
                    arrayList.add(classInfosDO);
                    getOrderMap(order).put(one, arrayList);
                } else {
                    list.add(classInfosDO);
                }
            }
        }

    }

    public static void compare() {
        Set<String> keySet = firstMap.keySet();
        List<String> keyList = new ArrayList<String>();
        keyList.addAll(keySet);
        Collections.sort(keyList);

        Map<String, List<String>> jarViewResult = new TreeMap<String, List<String>>();
        List<String> classViewResult = new ArrayList<String>();

        for (String fullClassName : keyList) {
            List<ClassInfosDO> list = secondMap.get(fullClassName);
            if (list != null) {
                //目录1
                StringBuffer input1SB = new StringBuffer();
                List<ClassInfosDO> value = firstMap.get(fullClassName);
                for (ClassInfosDO oneClassInfosDO : value) {
                    input1SB.append(" " + oneClassInfosDO.getJarName() + ",");
                }

                //目录2
                StringBuffer input2SB = new StringBuffer();
                for (ClassInfosDO oneClassInfosDO : list) {
                    input2SB.append(" " + oneClassInfosDO.getJarName() + ",");
                }

                classViewResult.add(fullClassName + "\tInput1: " + input1SB.toString()
                        + "\t input2: " + input2SB.toString());

                String jarKey = input1SB.toString() + " vs " + input2SB.toString();
                if (jarViewResult.get(jarKey) != null) {
                    jarViewResult.get(jarKey).add(fullClassName);
                } else {
                    List<String> classes = new ArrayList<String>();
                    classes.add(fullClassName);
                    jarViewResult.put(jarKey, classes);
                }
            }
        }

        writeResult(jarViewResult, classViewResult);
    }

    /**
     * 从jar的纬度和class的纬度分别输出结果
     */
    private static void writeResult(Map<String, List<String>> jarViewResult,
                                    List<String> classViewResult) {
        System.out.println("View From jar start.....");
        System.out.println("Total conflict jar num is " + jarViewResult.size());
        Set<Entry<String, List<String>>> entrySet = jarViewResult.entrySet();
        for (Entry<String, List<String>> one : entrySet) {
            String key = one.getKey();
            System.out.println("conflict jar name is" + key);
            for (String oneClassName : one.getValue()) {
                System.out.println("\t\t" + oneClassName);
            }
            System.out.println();
        }

        System.out.println("View From jar end!!!!");

        System.out.println("View From class start.....");
        System.out.println("Total conflict class num is " + classViewResult.size());
        for (String abc : classViewResult) {
            System.out.println(abc);
        }
        System.out.println("View From class end!!!!");
    }

    public static Map<String, List<ClassInfosDO>> getOrderMap(int order) {
        if (order == 1) {
            return firstMap;
        } else {
            return secondMap;
        }
    }

    public static void getAllClassName(String dir, List<String> allClassName, int length) {
        File file = new File(dir);
        File[] listFiles = file.listFiles();
        if (listFiles == null || listFiles.length == 0) {
            return;
        }

        for (File oneFile : listFiles) {
            String absolutePath = oneFile.getAbsolutePath();
            if (oneFile.isDirectory()) {
                getAllClassName(absolutePath, allClassName, length);
            } else {
                if (absolutePath.endsWith(".class")) {
                    allClassName.add(absolutePath.substring(length));
                }
            }
        }

    }

    //    public static void main(String[] args) {
    //        List<String> allClassName = new ArrayList<String>();
    //        getAllClassName("/tmp/1", allClassName, "/tmp/1".length() + 1);
    //        System.out.println(allClassName);
    //        System.out.println(allClassName.size());
    //
    //    }
}
package com.mikegu.tools.jardiff;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

public class ZipDecompression {
    //    public static void main(String[] args) throws IOException {
    //        String fileName = "toolkit.common.lang-1.0-sources.jar";
    //        decompression("C:/" + fileName, "C:/test");
    //    }

    public static void decompression(String zipFile, String destination) throws IOException {
        ZipFile zip;
        try {
            zip = new ZipFile(zipFile);
        } catch (IOException e) {
            System.out.println("error name " + zipFile);
            throw e;
        }
        Enumeration en = zip.entries();
        ZipEntry entry = null;
        byte[] buffer = new byte[8192];
        int length = -1;
        InputStream input = null;
        BufferedOutputStream bos = null;
        File file = null;

        while (en.hasMoreElements()) {
            entry = (ZipEntry) en.nextElement();
            if (entry.isDirectory()) {
                continue;
            }

            input = zip.getInputStream(entry);
            file = new File(destination, entry.getName());
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            bos = new BufferedOutputStream(new FileOutputStream(file));

            while (true) {
                length = input.read(buffer);
                if (length == -1)
                    break;
                bos.write(buffer, 0, length);
            }
            bos.close();
            input.close();
        }
        zip.close();
    }
}
 
扫描二维码关注公众号,回复: 645628 查看本文章
package com.mikegu.tools.jardiff;

/**
 * 类信息DO
 */
public class ClassInfosDO {

    private String classFullName;
    private String jarName;

    /**
     * @param classFullName
     * @param jarName
     */
    public ClassInfosDO(String classFullName, String jarName) {
        this.classFullName = classFullName;
        this.jarName = jarName;
    }

    /**
     * @return the classFullName
     */
    public String getClassFullName() {
        return classFullName;
    }

    /**
     * @param classFullName the classFullName to set
     */
    public void setClassFullName(String classFullName) {
        this.classFullName = classFullName;
    }

    /**
     * @return the jarName
     */
    public String getJarName() {
        return jarName;
    }

    /**
     * @param jarName the jarName to set
     */
    public void setJarName(String jarName) {
        this.jarName = jarName;
    }

}

猜你喜欢

转载自sesame.iteye.com/blog/1750458