你懂的呀,有时候我们需要判断某个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); } } }
感觉自己写的还算比较清楚吧,有不清楚的话我也是帮不了的。、。看代码吧~~~~