判断是否有jar包冲突

    你懂的呀,有时候我们需要判断某个lib目录下是否有jar包冲突,这毕竟是个让人头疼的问题。

    补充一句:这部分代码完全可以放在jsp中,即不需要重启容器也能够进行检测。

    一般分为两种情况。

    一是已知包里有某个类,一般用在自己发布的jar包上面,因为可以进行约束。此时通过当前线程的类加载器获取资源,如果有重复说明有冲突。

    //写入需要检测的class,格式如com.zang.ai.WangShao
    private static final List<String> classList=Arrays.asList("com.zang.ai.WangShao");
    //检测特定列表class是否冲突
    private void checkClassList(){
        for(String str:classList){
            String classpath=str.replaceAll("\\.","/")+".class";
            checkClassDuplicate(classpath);
        }
    }

    //检测class是否冲突
    private boolean checkClassDuplicate(String classpath){
        boolean isDuplicate=false;
        try {
            // 在ClassPath搜文件
            Enumeration urls = Thread.currentThread().getContextClassLoader().getResources(classpath);
            Set files = new HashSet();
            while (urls.hasMoreElements()) {
                URL url = (URL) urls.nextElement();
                if (url != null) {
                    String file = url.getFile();
                    if (file != null && file.length() > 0) {
                        files.add(file);
                    }
                }
            }
            // 如果有多个,就表示重复
            if (files.size() > 1) {
                Iterator<String> it = files.iterator();
                boolean isDuplicate= true;
                System.out.println("-------------------------------");
                while (it.hasNext()) {
                    //这样取jar包名称未必准确
                    String str = it.next().replaceAll("\\.jar!.*", ".jar");
                    System.out.println(str);
                }
            }else if(files.size()==0){
                //0表示缺失
            }
        } catch (Throwable e) {
            // 防御性容错
        }
        return isDuplicate;}

    还有一种情况,对于第三方这种不好控制的jar包,我们无法保证其某些class名称不冲突,此时需要根据其jar包名称去进行判断。先根据jar包中MANIFEST.MF文件去取名称,没有的话再通过包名称获取。

    private static final Pattern VERSION_PATTERN = Pattern.compile("(-[0-9][0-9a-zA-Z_\\.\\-]*)\\.jar");

    private Map<String,List<String>> noepointjar=new HashMap<String,List<String>>();
	
	//遍历jar包
    private void getAllJarName(String libpath){
	File libfile=new File(libpath);
        try {
            File[] files = libfile.listFiles();
            for (File f : files) {
                if (f.isDirectory()) {
                    getAllJarName(f.getPath());
                }
                if (f.isFile() && f.getName().endsWith(".jar")) {
                    String name=getJarName(f.getPath());
                    if(name!=null && name.length()>0) {
                        putMap(name, f.getPath());
                    }
                }
            }
        }catch (Exception e){
            //防止地址错误
        }
    }

    //得到jar包包名
    private String getJarName(String jarpath){
        String name = "";
        JarFile jarFile = null;
        try {
            jarFile = new JarFile(jarpath);
            Manifest manifest = jarFile.getManifest();
	    //防止一些杂牌jar包没有manifest配置文件......
	    //另外,其他一些内容也可以通过修改getValue中的属性来获取,比如版本号等等信息,详情参考MANIFEST.MF文件内容。
            if(manifest!=null) {
                Attributes att = manifest.getMainAttributes();
                Map<String, Attributes> map = manifest.getEntries();
				//有些jar包的信息放置在其签名之下,无法直接获取。
                for (String str : map.keySet()) {
                    String temp = map.get(str).getValue("Implementation-Title");
                    if (temp != null && temp.length() > 0) {
                        name = temp;
                        //只取第一个
                        break;
                    }
                }
                if (name == null || name.length() == 0) {
                    name = att.getValue("Implementation-Title");
                }
                if (name == null || name.length() == 0) {
                    name = att.getValue("Specification-Title");
                }
            }
            if (name == null || name.length() == 0) {
                Matcher matcher = VERSION_PATTERN.matcher(jarpath);
                while (matcher.find() && matcher.groupCount() > 0) {
                    //Jarfile的getName方法会得到路径,需要截取
                    String[] jarname=jarFile.getName().split("\\\\");
                    name=jarname[jarname.length-1].replace(matcher.group(0),"");
                }
            }
        }catch (IOException e1) {
            //我防
        }
        return name;
    }

    private void putMap(String jarname,String jarpath){
        if(noepointjar.containsKey(jarname)){
            List<String> jarpathlist=noepointjar.get(jarname);
            jarpathlist.add(jarpath);
            noepointjar.put(jarname,jarpathlist);
        }else {
            List<String> jarpathlist=new ArrayList<String>();
            jarpathlist.add(jarpath);
            noepointjar.put(jarname,jarpathlist);
        }
    }

    //遍历map
    private void checkMap(){
        for (String key : noepointjar.keySet()) {
            List<String> temp=noepointjar.get(key);
            //大于1存在冲突
            if(temp.size()>1){
		System.out.println("----------------------------------");
                for(String str:temp){
		    System.out.println(str);
            }
        }
    }

感觉自己写的还算比较清楚吧,有不清楚的话我也是帮不了的。、。看代码吧~~~~

猜你喜欢

转载自blog.csdn.net/danengbinggan33/article/details/78582835
今日推荐