代码之家  ›  专栏  ›  技术社区  ›  David Citron

是否有工具可以发现类路径中的多个JAR中是否存在相同的类?

  •  18
  • David Citron  · 技术社区  · 16 年前

    我正在寻找一种工具,可以检测和标记给定类路径或文件夹集中的此类潜在冲突。

    当然,这是一个开始的脚本:

    classes=`mktemp`
    for i in `find . -name "*.jar"`
    do
        echo "File: $i" > $classes
        jar tf $i > $classes
        ...
    done
    

    稍后使用一些聪明的sort/uniq/diff/grep/awk有潜力,但我想知道是否有人知道任何现有的解决方案。

    7 回复  |  直到 16 年前
        1
  •  9
  •   Zac Thompson    14 年前

    看起来像 jarfish 将使用其“dups”命令执行您想要的操作。

        2
  •  8
  •   Zac Thompson    14 年前

    这个 Tattletale JBoss中的工具是另一个候选工具:“如果一个类/包位于多个JAR文件中,则发现”

        3
  •  4
  •   OscarRyz    16 年前

    您可以使用System.getProperty(“java.class.path”)获取类路径条目;

    然后遍历列出的JAR、ZIP或目录,收集所有关于类的信息,并查找可能导致问题的信息。

    此任务最多需要1或2天。然后可以直接在应用程序中加载此类并生成报告。

    如果您在一些具有复杂自定义类加载的基础设施中运行(例如,我曾经看到一个应用程序从LDAP加载类),java.class.path属性可能不会显示所有类,但它肯定适用于大多数情况。

    这里有一个你可能会觉得有用的工具,我自己从来没有用过,但是试一下,让我们知道结果。

    http://www.jgoodies.com/freeware/jpathreport/features.html

    您可以使用它并对其进行修改,以便读取类路径并比较.class-time属性,而不是递归地遍历目录。

    有一个命令类,如果需要的话,可以将其子类化,我在“find”的-execute选项中考虑过

    这是我自己的代码,所以它不是为了“生产就绪”,只是为了完成工作。

    import java.io.*;
    import java.util.zip.*;
    
    
    public class ListZipContent{
        public static void main( String [] args ) throws IOException {
            System.out.println( "start " + new java.util.Date() );
            String pattern = args.length == 1 ? args[0] : "OracleDriver.class";// Guess which class I was looking for :) 
            File file = new File(".");
            FileFilter fileFilter = new FileFilter(){
                public boolean accept( File file ){
                    return file.isDirectory() || file.getName().endsWith( "jar" );
                }
            };
            Command command = new Command( pattern );
            executeRecursively( command, file, fileFilter );
            System.out.println( "finish  " + new java.util.Date() );
        }
        private static void executeRecursively( Command command, File dir , FileFilter filter ) throws IOException {
            if( !dir.isDirectory() ){
                System.out.println( "not a directory " + dir );
                return;
            }
            for( File file : dir.listFiles( filter ) ){
                if( file.isDirectory()){
                    executeRecursively( command,file , filter );
                }else{
                    command.executeOn( file );
                }
            }
        }
    }
    class Command {
    
        private String pattern;
        public Command( String pattern ){
            this.pattern = pattern;
        }
    
        public void executeOn( File file ) throws IOException {
            if( pattern == null ) { 
                System.out.println( "Pattern is null ");
                return;
            }
    
            String fileName = file.getName();
            boolean jarNameAlreadyPrinted = false;
    
            ZipInputStream zis = null;
            try{
                zis = new ZipInputStream( new FileInputStream( file ) );
    
                ZipEntry ze;
                while(( ze = zis.getNextEntry() ) != null ) {
                    if( ze.getName().endsWith( pattern )){
                        if( !jarNameAlreadyPrinted ){
                            System.out.println("Contents of: " + file.getCanonicalPath()  );
                            jarNameAlreadyPrinted = true;
                        }
                        System.out.println( "    " + ze.getName() );
                    }
                    zis.closeEntry();
                }
            }finally{
                if( zis != null ) try {
                    zis.close();
                }catch( Throwable t ){}
            }
        }
    }
    

    我希望这有帮助。

        4
  •  3
  •   ferbs    16 年前

    Classpath Helper 是一个Eclipse插件,它有一点帮助。

        5
  •  2
  •   Chris Seline    9 年前

    如果您不喜欢下载和安装东西,您可以使用这一行命令来查找jar与标准gnu工具的冲突。这是初步的,但你可以扩展它,因为你想。

    ls *.jar | xargs -n1 -iFILE unzip -l FILE | grep class | sed "s,.* ,," | tr "/" "." | sort | uniq -d | xargs -n1 -iCLASS grep -l CLASS *.jar | sort -u
    

    (如果你有很多罐子,跑起来有点慢)

    它列出所有jar中的所有文件,greps表示类文件,查找重复项,然后greps原始jar以查看它们出现的位置。使用更复杂的脚本可以提高效率。

        6
  •  0
  •   s_t_e_v_e    16 年前

    jarclassfinder 是另一个eclipse插件选项