Existe uma ferramenta para descobrir se a mesma classe existe em vários frascos no classpath?

StackOverflow https://stackoverflow.com/questions/135971

  •  02-07-2019
  •  | 
  •  

Pergunta

Se você tiver dois frascos em seu caminho de classe que contêm diferentes versões da mesma classe, a ordem de classpath torna-se crítica.

Eu estou procurando uma ferramenta que pode detectar e bandeira tais conflitos potenciais em um determinado caminho de classe ou conjunto de pastas.

Certamente um script que começa:

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

com algum tipo inteligente / uniq / diff / grep / awk, mais tarde, tem potencial, mas eu queria saber se alguém sabe de todas as soluções existentes.

Foi útil?

Solução

O Tattletale ferramenta da JBoss é outro candidato: "Pontual se uma classe / pacote está localizado em múltiplos arquivos JAR "

Outras dicas

Looks como jarfish vai fazer o que quiser com o seu comando "ingênuos" .

Eu acho que não seria muito difícil escrever uma ferramenta para o seu self.

Você pode obter as entradas de classpath com System.getProperty ( "java.class.path");

E, em seguida, percorrer os frascos, zips, ou diretórios listados lá e recolher todas as informações sobre as classes e findout aqueles que podem causar problemas.

Esta tarefa levaria 1 ou 2 dias, no máximo. Então você pode carregar esta classe diretamente em seu aplicativo e gerar um relatório.

Provavelmente propriedade java.class.path costume de mostrar todas as classes se você executar em algumas infra-estruturas com complexo de carregamento de classe personalizada (por exemplo, uma vez eu vi um app que carregar as classes do LDAP), mas seria certamente trabalho para a maioria dos os casos.

Aqui está uma ferramenta que você pode achar útil, eu nunca usá-lo minha auto, mas dar-lhe uma tentativa e deixe-nos saber o resultado.

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

Se você estiver indo para criar sua própria ferramenta, aqui está o código que eu uso para o mesmo script shell postado antes, mas que eu uso na minha máquina Windows. Corre-se mais rápido quando há toneladas de arquivos jar.

Você pode usá-lo e modificá-lo assim em vez de forma recursiva andar um diretório, ler o caminho de classe e comparar o atributo tempo .class.

Há uma classe de comando que você pode subclasse, se necessário, eu estava pensando na opção -execute de "encontrar"

Este meu próprio código, de modo que não se destinava a ser "produção pronta", só para fazer o trabalho.

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 ){}
        }
    }
}

Espero que isso ajude.

Classpath Helper é um plug-in Eclipse que ajuda um pouco.

Se você não gosta de baixar e instalar material que você pode usar este comando uma linha para encontrar conflitos frasco com ferramentas GNU padrão. É rudimentar, mas você pode expandi-lo como quiser.

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

(é um pouco lento para ser executado se você tem um monte de frascos)

Explicação: Ele lista todos os arquivos em todos os frascos, greps para arquivos de classe, acha tolos, então greps os frascos originais para ver onde eles apareceram. Pode ser feito mais eficiente com um roteiro mais complicado.

jarclassfinder é outra opção eclipse plug-in

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top