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